public void ShouldCalculateTeamResultCorrectForFifthGen2()
        {
            var fightInfo = new FightInformation
            {
                EnemyBaseExperience = 77, // Lickitung
                EnemyIsWild = false,
                EnemyLevel = 62,
                Team = new List<Fighter>
                {
                    new Fighter { HasParticipated = true, Level = 31, TradeState = TradeState.TradedNational },
                    new Fighter { HasParticipated = true, Level = 65 },
                    new Fighter(),
                    new Fighter(),
                    new Fighter(),
                    new Fighter { HoldsExpShare = true, Level = 16, TradeState = TradeState.TradedNational }
                }
            };

            IList<Fighter> result = _service.CalculateBattleResult(5, fightInfo);

            Assert.AreEqual(1038, result[0].EarnedExperience);
            Assert.AreEqual(339, result[1].EarnedExperience);
            Assert.AreEqual(0, result[2].EarnedExperience);
            Assert.AreEqual(0, result[3].EarnedExperience);
            Assert.AreEqual(0, result[4].EarnedExperience);
            Assert.AreEqual(3073, result[5].EarnedExperience);
        }
        public void ShouldCalculateTeamResultCorrectForFifthGen1()
        {
            var fightInfo = new FightInformation
            {
                EnemyBaseExperience = 87, // Tangela
                EnemyIsWild = true,
                EnemyLevel = 36,
                Team = new List<Fighter>
                {
                    new Fighter { HasParticipated = true, Level = 31, TradeState = TradeState.TradedNational },
                    new Fighter(),
                    new Fighter { HasParticipated = true, HoldsLuckyEgg = true, Level = 66 },
                    new Fighter { HasParticipated = true, Level = 67 },
                    new Fighter { HasParticipated = true, Level = 76 },
                    new Fighter { HoldsExpShare = true, Level = 15, TradeState = TradeState.TradedNational }
                }
            };

            IList<Fighter> result = _service.CalculateBattleResult(5, fightInfo);

            Assert.AreEqual(138, result[0].EarnedExperience);
            Assert.AreEqual(0, result[1].EarnedExperience);
            Assert.AreEqual(54, result[2].EarnedExperience);
            Assert.AreEqual(35, result[3].EarnedExperience);
            Assert.AreEqual(29, result[4].EarnedExperience);
            Assert.AreEqual(984, result[5].EarnedExperience);
        }
        public IList<Fighter> CalculateBattleResult(byte generation, FightInformation fightInfo)
        {
            byte participated = Convert.ToByte(fightInfo.Team.Count(c => c.HasParticipated));
            if (participated == 0)
                throw new Exception("There can be no fight without participants");

            byte teamCount = 0;
            byte expShareCount = 0;

            if (generation == 1)
            {
                if (fightInfo.ExpAllActive)
                    teamCount = Convert.ToByte(fightInfo.Team.Count);
            }
            else
                expShareCount = Convert.ToByte(fightInfo.Team.Count(c => c.HoldsExpShare));

            // Loop through all team members
            foreach (Fighter fighter in fightInfo.Team)
            {
                if (fighter.HasParticipated)
                {
                    // Calculate experience that is earned directly through actively defeating the enemy
                    if (generation == 1)
                        fighter.EarnedExperience = _experienceCalculator.CalculateExperienceForFirstGen(fightInfo.EnemyBaseExperience, fightInfo.EnemyLevel, participated, fightInfo.EnemyIsWild, fighter.TradeState == TradeState.TradedNational, fightInfo.ExpAllActive, 0);
                    else if (generation == 6)
                        fighter.EarnedExperience = _experienceCalculator.CalculateExperienceForSixthGen(fightInfo.EnemyBaseExperience, fightInfo.EnemyLevel, fightInfo.EnemyIsWild, fighter.TradeState, fighter.HoldsLuckyEgg, fightInfo.ExpPowerState, fighter.HasAffection, fighter.CouldEvolved, fightInfo.ExpAllActive, true);
                    else
                        fighter.EarnedExperience = CalculateExperienceYield(generation, fightInfo.EnemyBaseExperience, fightInfo.EnemyLevel, fighter.Level, participated, fightInfo.EnemyIsWild, fighter.TradeState, fighter.HoldsLuckyEgg, expShareCount, false, fightInfo.ExpPowerState);
                }

                // if the active fighter also holds Exp.Share he will be given both direct exp from fight and Exp.Share output, so we sum them
                if (fighter.HoldsExpShare && generation > 1)
                    fighter.EarnedExperience += CalculateExperienceYield(generation, fightInfo.EnemyBaseExperience, fightInfo.EnemyLevel, fighter.Level, 1, fightInfo.EnemyIsWild, fighter.TradeState, fighter.HoldsLuckyEgg, expShareCount, true, fightInfo.ExpPowerState);

                // In first gen with activated Exp.All you get half the Exp + the Exp.All output so we calculate both and sum them
                if (teamCount > 0 && generation == 1)
                    fighter.EarnedExperience += _experienceCalculator.CalculateExperienceForFirstGen(fightInfo.EnemyBaseExperience, fightInfo.EnemyLevel, participated, fightInfo.EnemyIsWild, fighter.TradeState == TradeState.TradedNational, fightInfo.ExpAllActive, teamCount);

                // Not sure about this, but all tests seemed to have shown that this is neccessary
                // More tests are needed to evaluate this, maybe Exp Calc is wrong somewhere
                if (generation == 5 && fighter.HasParticipated && fighter.HoldsExpShare && expShareCount > 1)
                    fighter.EarnedExperience = fighter.EarnedExperience - 1;

                if (generation == 6 && fightInfo.ExpAllActive)
                    fighter.EarnedExperience = _experienceCalculator.CalculateExperienceForSixthGen(fightInfo.EnemyBaseExperience, fightInfo.EnemyLevel, fightInfo.EnemyIsWild, fighter.TradeState, fighter.HoldsLuckyEgg, fightInfo.ExpPowerState, fighter.HasAffection, fighter.CouldEvolved, fightInfo.ExpAllActive, false);
            }

            return fightInfo.Team;
        }
        public void ShouldCalculateTeamResultCorrectForFifthGen3()
        {
            var fightInfo = new FightInformation
            {
                EnemyBaseExperience = 168, // Darmanitan
                EnemyIsWild = false,
                EnemyLevel = 62,
                Team = new List<Fighter>
                {
                    new Fighter(),
                    new Fighter(),
                    new Fighter { HasParticipated = true, HoldsLuckyEgg = true, Level = 66 },
                    new Fighter(),
                    new Fighter(),
                    new Fighter { HoldsExpShare = true, Level = 25, TradeState = TradeState.TradedNational }
                }
            };

            IList<Fighter> result = _service.CalculateBattleResult(5, fightInfo);

            Assert.AreEqual(0, result[0].EarnedExperience);
            Assert.AreEqual(0, result[1].EarnedExperience);
            Assert.AreEqual(2178, result[2].EarnedExperience);
            Assert.AreEqual(0, result[3].EarnedExperience);
            Assert.AreEqual(0, result[4].EarnedExperience);
            Assert.AreEqual(5256, result[5].EarnedExperience);
        }
        public void ShouldCalculateTeamResultCorrectForThirdGen4()
        {
            var fightInfo = new FightInformation
            {
                EnemyBaseExperience = 181, // Shiftry
                EnemyIsWild = false,
                EnemyLevel = 48,
                Team = new List<Fighter>
                {
                    new Fighter { HasParticipated = true, HoldsLuckyEgg = true },
                    new Fighter { HasParticipated = true },
                    new Fighter { HasParticipated = true, HoldsLuckyEgg = true, TradeState = TradeState.TradedNational },
                    new Fighter { HasParticipated = true },
                    new Fighter { HoldsExpShare = true, TradeState = TradeState.TradedNational },
                    new Fighter()
                }
            };

            IList<Fighter> result = _service.CalculateBattleResult(3, fightInfo);

            Assert.AreEqual(348, result[0].EarnedExperience);
            Assert.AreEqual(232, result[1].EarnedExperience);
            Assert.AreEqual(522, result[2].EarnedExperience);
            Assert.AreEqual(232, result[3].EarnedExperience);
            Assert.AreEqual(1395, result[4].EarnedExperience);
            Assert.AreEqual(0, result[5].EarnedExperience);
        }
        public void ShouldCalculateTeamResultCorrectForThirdGen3()
        {
            var fightInfo = new FightInformation
            {
                EnemyBaseExperience = 128, // Mightyena
                EnemyIsWild = false,
                EnemyLevel = 46,
                Team = new List<Fighter>
                {
                    new Fighter { HasParticipated = true, HoldsLuckyEgg = true },
                    new Fighter { HasParticipated = true },
                    new Fighter { HasParticipated = true, HoldsLuckyEgg = true, TradeState = TradeState.TradedNational },
                    new Fighter { HasParticipated = true },
                    new Fighter { HasParticipated = true, HoldsExpShare = true, TradeState = TradeState.TradedNational },
                    new Fighter { HasParticipated = true, TradeState = TradeState.TradedNational }
                }
            };

            IList<Fighter> result = _service.CalculateBattleResult(3, fightInfo);

            Assert.AreEqual(157, result[0].EarnedExperience);
            Assert.AreEqual(105, result[1].EarnedExperience);
            Assert.AreEqual(235, result[2].EarnedExperience);
            Assert.AreEqual(105, result[3].EarnedExperience);
            Assert.AreEqual(1102, result[4].EarnedExperience);
            Assert.AreEqual(157, result[5].EarnedExperience);
        }
        public void ShouldCalculateTeamResultCorrectForThirdGen2()
        {
            var fightInfo = new FightInformation
            {
                EnemyBaseExperience = 171, // Golbat
                EnemyIsWild = true,
                EnemyLevel = 40,
                Team = new List<Fighter>
                {
                    new Fighter(),
                    new Fighter { HasParticipated = true },
                    new Fighter(),
                    new Fighter { HasParticipated = true },
                    new Fighter { HasParticipated = true, HoldsExpShare = true, TradeState = TradeState.TradedNational },
                    new Fighter { HasParticipated = true, TradeState = TradeState.TradedNational }
                }
            };

            IList<Fighter> result = _service.CalculateBattleResult(3, fightInfo);

            Assert.AreEqual(0, result[0].EarnedExperience);
            Assert.AreEqual(122, result[1].EarnedExperience);
            Assert.AreEqual(0, result[2].EarnedExperience);
            Assert.AreEqual(122, result[3].EarnedExperience);
            Assert.AreEqual(915, result[4].EarnedExperience);
            Assert.AreEqual(183, result[5].EarnedExperience);
        }
        public void ShouldCalculateTeamResultCorrectForSecondGen8()
        {
            var fightInfo = new FightInformation
            {
                EnemyBaseExperience = 171, // Xatu
                EnemyIsWild = false,
                EnemyLevel = 42,
                Team = new List<Fighter>
                {
                    new Fighter(),
                    new Fighter(),
                    new Fighter { HasParticipated = true, TradeState = TradeState.TradedNational },
                    new Fighter(),
                    new Fighter(),
                    new Fighter { HasParticipated = true, HoldsExpShare = true }
                }
            };

            IList<Fighter> result = _service.CalculateBattleResult(2, fightInfo);

            Assert.AreEqual(0, result[0].EarnedExperience);
            Assert.AreEqual(0, result[1].EarnedExperience);
            Assert.AreEqual(567, result[2].EarnedExperience);
            Assert.AreEqual(0, result[3].EarnedExperience);
            Assert.AreEqual(0, result[4].EarnedExperience);
            Assert.AreEqual(1143, result[5].EarnedExperience);
        }
        public void ShouldCalculateTeamResultCorrectForSecondGen3()
        {
            var fightInfo = new FightInformation
            {
                EnemyBaseExperience = 189, // Donphan
                EnemyIsWild = true,
                EnemyLevel = 33,
                Team = new List<Fighter>
                {
                    new Fighter { HoldsExpShare = true },
                    new Fighter { HasParticipated = true, TradeState = TradeState.TradedNational },
                    new Fighter(),
                    new Fighter(),
                    new Fighter { HasParticipated = true },
                    new Fighter()
                }
            };

            IList<Fighter> result = _service.CalculateBattleResult(2, fightInfo);

            Assert.AreEqual(443, result[0].EarnedExperience);
            Assert.AreEqual(331, result[1].EarnedExperience);
            Assert.AreEqual(0, result[2].EarnedExperience);
            Assert.AreEqual(0, result[3].EarnedExperience);
            Assert.AreEqual(221, result[4].EarnedExperience);
            Assert.AreEqual(0, result[5].EarnedExperience);
        }
        public void ShouldCalculateTeamResultCorrectForFourthGen4()
        {
            var fightInfo = new FightInformation
            {
                EnemyBaseExperience = 91, // Growlithe
                EnemyIsWild = true,
                EnemyLevel = 18,
                Team = new List<Fighter>
                {
                    new Fighter { HasParticipated = true, HoldsExpShare = true },
                    new Fighter { HasParticipated = true },
                    new Fighter(),
                    new Fighter { HasParticipated = true, HoldsExpShare = true, TradeState = TradeState.TradedNational },
                    new Fighter(),
                    new Fighter()
                }
            };

            IList<Fighter> result = _service.CalculateBattleResult(4, fightInfo);

            Assert.AreEqual(97, result[0].EarnedExperience);
            Assert.AreEqual(39, result[1].EarnedExperience);
            Assert.AreEqual(0, result[2].EarnedExperience);
            Assert.AreEqual(145, result[3].EarnedExperience);
            Assert.AreEqual(0, result[4].EarnedExperience);
            Assert.AreEqual(0, result[5].EarnedExperience);
        }
        public void ShouldCalculateTeamResultCorrectForFirstGen4()
        {
            var fightInfo = new FightInformation
            {
                EnemyBaseExperience = 203, // Cloyster
                EnemyIsWild = false,
                EnemyLevel = 53,
                ExpAllActive = true,
                Team = new List<Fighter>
                {
                    new Fighter { HasParticipated = true, TradeState = TradeState.TradedNational },
                    new Fighter { TradeState = TradeState.TradedNational },
                    new Fighter { HasParticipated = true },
                    new Fighter(),
                    new Fighter { TradeState = TradeState.TradedNational },
                    new Fighter { TradeState = TradeState.TradedNational }
                }
            };

            IList<Fighter> result = _service.CalculateBattleResult(1, fightInfo);

            Assert.AreEqual(985, result[0].EarnedExperience);
            Assert.AreEqual(135, result[1].EarnedExperience);
            Assert.AreEqual(657, result[2].EarnedExperience);
            Assert.AreEqual(90, result[3].EarnedExperience);
            Assert.AreEqual(135, result[4].EarnedExperience);
            Assert.AreEqual(135, result[5].EarnedExperience);
        }
        public void ShouldCalculateTeamResultCorrectForFirstGen3()
        {
            var fightInfo = new FightInformation
            {
                EnemyBaseExperience = 151, // Weepinbell
                EnemyIsWild = true,
                EnemyLevel = 30,
                ExpAllActive = true,
                Team = new List<Fighter>
                {
                    new Fighter { HasParticipated = true, TradeState = TradeState.TradedNational },
                    new Fighter { TradeState = TradeState.TradedNational },
                    new Fighter(),
                    new Fighter(),
                    new Fighter { TradeState = TradeState.TradedNational },
                    new Fighter { TradeState = TradeState.TradedNational }
                }
            };

            IList<Fighter> result = _service.CalculateBattleResult(1, fightInfo);

            Assert.AreEqual(557, result[0].EarnedExperience);
            Assert.AreEqual(76, result[1].EarnedExperience);
            Assert.AreEqual(51, result[2].EarnedExperience);
            Assert.AreEqual(51, result[3].EarnedExperience);
            Assert.AreEqual(76, result[4].EarnedExperience);
            Assert.AreEqual(76, result[5].EarnedExperience);
        }
        public void ShouldCalculateTeamResultCorrectForFirstGen1()
        {
            var fightInfo = new FightInformation
            {
                EnemyBaseExperience = 164, // Slowbro
                EnemyIsWild = false,
                EnemyLevel = 54,
                ExpAllActive = false,
                Team = new List<Fighter>
                {
                    new Fighter { HasParticipated = true, TradeState = TradeState.TradedNational },
                    new Fighter(),
                    new Fighter(),
                    new Fighter(),
                    new Fighter { HasParticipated = true, TradeState = TradeState.TradedNational },
                    new Fighter()
                }
            };

            IList<Fighter> result = _service.CalculateBattleResult(1, fightInfo);

            Assert.AreEqual(1422, result[0].EarnedExperience);
            Assert.AreEqual(0, result[1].EarnedExperience);
            Assert.AreEqual(0, result[2].EarnedExperience);
            Assert.AreEqual(0, result[3].EarnedExperience);
            Assert.AreEqual(1422, result[4].EarnedExperience);
            Assert.AreEqual(0, result[5].EarnedExperience);
        }
        public void ShouldCalculateTeamResultCorrectForFifthGen7()
        {
            var fightInfo = new FightInformation
            {
                EnemyBaseExperience = 179, // Mienshao
                EnemyIsWild = true,
                EnemyLevel = 56,
                Team = new List<Fighter>
                {
                    new Fighter { HasParticipated = true, HoldsExpShare = true, Level = 68 },
                    new Fighter { HasParticipated = true, Level = 66 },
                    new Fighter(),
                    new Fighter(),
                    new Fighter(),
                    new Fighter { HasParticipated = true, HoldsExpShare = true, Level = 29, TradeState = TradeState.TradedNational }
                }
            };

            IList<Fighter> result = _service.CalculateBattleResult(5, fightInfo);

            Assert.AreEqual(661, result[0].EarnedExperience);
            Assert.AreEqual(275, result[1].EarnedExperience);
            Assert.AreEqual(0, result[2].EarnedExperience);
            Assert.AreEqual(0, result[3].EarnedExperience);
            Assert.AreEqual(0, result[4].EarnedExperience);
            Assert.AreEqual(2341, result[5].EarnedExperience);
        }
        public void ShouldCalculateTeamResultCorrectForFifthGen6()
        {
            var fightInfo = new FightInformation
            {
                EnemyBaseExperience = 166, // Sawsbuck
                EnemyIsWild = true,
                EnemyLevel = 55,
                Team = new List<Fighter>
                {
                    new Fighter { HasParticipated = true, HoldsExpShare = true, Level = 68 },
                    new Fighter { HasParticipated = true, Level = 66 },
                    new Fighter { HasParticipated = true, HoldsLuckyEgg = true, Level = 67 },
                    new Fighter(),
                    new Fighter(),
                    new Fighter { HoldsExpShare = true, Level = 28, TradeState = TradeState.TradedNational }
                }
            };

            IList<Fighter> result = _service.CalculateBattleResult(5, fightInfo);

            Assert.AreEqual(588, result[0].EarnedExperience);
            Assert.AreEqual(245, result[1].EarnedExperience);
            Assert.AreEqual(360, result[2].EarnedExperience);
            Assert.AreEqual(0, result[3].EarnedExperience);
            Assert.AreEqual(0, result[4].EarnedExperience);
            Assert.AreEqual(1294, result[5].EarnedExperience);
        }