public void should_insert_zombie_pack_progress_that_does_exist()
 {
     UserZombiePackProgress progress = new UserZombiePackProgress { MaxZombies = 100, IsDestroyed = true, ZombiesLeft = 25 };
     _userZombiePackProgressSaver.SaveZombiePackProgress(_userId, _zombiePackId, progress);
     using (TestDataContext dataContext = new TestDataContext(_connectionString))
     {
         var dto = dataContext.UserZombiePackProgressDtos.Single(s => s.UserId == _userId && s.ZombiePackId == _zombiePackId);
         Assert.AreEqual(_userId, dto.UserId);
         Assert.AreEqual(_zombiePackId, dto.ZombiePackId);
         Assert.AreEqual(100, dto.MaxZombies);
         Assert.AreEqual(25, dto.ZombiesLeft);
         Assert.AreEqual(true, dto.IsDestroyed);
     }
 }
        public void should_return_current_zombie_pack_progress_if_user_has_already_visited_zombie_pack()
        {
            Guid userId = Guid.NewGuid();
            Guid zombiePackId = Guid.NewGuid();

            _userRetriever.Setup(s => s.UserExists(userId)).Returns(true);
            _zombiePackRetriever.Setup(s => s.ZombiePackExists(zombiePackId)).Returns(true);

            UserZombiePackProgress progress = new UserZombiePackProgress{ IsDestroyed = false, MaxZombies = 10, ZombiesLeft = 5 };
            _userZombiePackProgressRetriever.Setup(s => s.GetUserZombiePackProgressFor(userId, zombiePackId))
                                            .Returns(progress as IUserZombiePackProgress)
                                            .Verifiable();

            IUserZombiePackProgress returnedProgress = _zombiePackDifficultyDirector.GetCalculatedZombiePackProgress(userId, zombiePackId);
            Assert.AreEqual(false, returnedProgress.IsDestroyed);
            Assert.AreEqual(10, returnedProgress.MaxZombies);
            Assert.AreEqual(5, returnedProgress.ZombiesLeft);
            _userZombiePackProgressRetriever.Verify();
        }
        IUserZombiePackProgress IZombiePackDifficultyDirector.GetCalculatedZombiePackProgress(Guid userId, Guid zombiePackId)
        {
            UserZombiePackProgress progress = new UserZombiePackProgress
            {
                IsDestroyed = false,
                ZombiesLeft = 0,
                MaxZombies = 0
            };

            if (_userRetriever.UserExists(userId) == false)
            {
                return progress;
            }

            if (_zombiePackRetriever.ZombiePackExists(zombiePackId) == false)
            {
                return progress;
            }

            IUserZombiePackProgress progressFromRepository = _userZombiePackProgressRetriever.GetUserZombiePackProgressFor(userId, zombiePackId);
            if (progressFromRepository != null)
            {
                return progressFromRepository;
            }

            DetermineBaseLineRecalc(userId, zombiePackId);

            int baselineAttack = _userRetriever.GetAttackPowerForDifficultyCalculation(userId);
            int numberOfHunts = GetNumberOfHuntsToDestroy();
            int zombieCount = baselineAttack * numberOfHunts;
            progress = new UserZombiePackProgress
            {
                IsDestroyed = false,
                ZombiesLeft = zombieCount,
                MaxZombies = zombieCount
            };

            _userZombiePackProgressSaver.SaveZombiePackProgress(userId, zombiePackId, progress);

            return progress;
        }
        public void should_update_existing_zombie_pack_progress()
        {
            UserZombiePackProgress progress = new UserZombiePackProgress { MaxZombies = 100, IsDestroyed = true, ZombiesLeft = 25 };
            _userZombiePackProgressSaver.SaveZombiePackProgress(_userId, _zombiePackId, progress);

            //update
            progress.ZombiesLeft = 10;
            progress.MaxZombies = 20;
            progress.IsDestroyed = false;
            _userZombiePackProgressSaver.SaveZombiePackProgress(_userId, _zombiePackId, progress);

            using (TestDataContext dataContext = new TestDataContext(_connectionString))
            {
                var dto = dataContext.UserZombiePackProgressDtos.Single(s => s.UserId == _userId && s.ZombiePackId == _zombiePackId);
                Assert.AreEqual(_userId, dto.UserId);
                Assert.AreEqual(_zombiePackId, dto.ZombiePackId);
                Assert.AreEqual(20, dto.MaxZombies);
                Assert.AreEqual(10, dto.ZombiesLeft);
                Assert.AreEqual(false, dto.IsDestroyed);
            }
        }
        void IHuntDirector.Hunt(Guid userId, Guid zombiePackId)
        {
            //hunt can only occur if user exists
            if (_userRetriever.UserExists(userId) == false)
            {
                return;
            }

            //and if the zombie pack existss
            if (_zombiePackRetriever.ZombiePackExists(zombiePackId) == false)
            {
                return;
            }

            //and if the user's current location is the location of the zombie pack
            IUser user = _userRetriever.GetUserById(userId);
            IZombiePack zombiePack = _zombiePackRetriever.GetZombiePackById(zombiePackId);

            if (user.Latitude != zombiePack.Latitude || user.Longitude != zombiePack.Longitude)
            {
                return;
            }

            //if the user is indeed at the given zombie pack, make sure to update the users zone id to 
            //be the hotzone the user is located in
            _userSaver.UpdateZone(userId, _zombiePackRetriever.GetHotZoneByZombiePackId(zombiePackId));

            //and if the user has enough energy to hunt
            int userEnergy = _userEnergyProvider.GetUserEnergy(userId, DateTime.Now);
            int energyRequiredToHunt = _zombiePackDifficultyDirector.GetEnergyCost(userId, zombiePackId);
            if (userEnergy < energyRequiredToHunt)
            {
                return;
            }

            //update the progress for the hunt
            IUserZombiePackProgress progress = _zombiePackDifficultyDirector.GetCalculatedZombiePackProgress(userId, zombiePackId);

            if (progress.ZombiesLeft == 0)
            {
                return;
            }

            //update the user's energy
            _userSaver.SaveLastEnergy(userId, userEnergy - energyRequiredToHunt, DateTime.Now);

            int userAttackPower = _userAttackPowerProvider.GetAttackPower(userId);

            UserZombiePackProgress newProgress = new UserZombiePackProgress
            {
                ZombiesLeft = progress.ZombiesLeft - userAttackPower,
                MaxZombies = progress.MaxZombies,
                IsDestroyed = false
            };

            if (newProgress.ZombiesLeft < 0)
            {
                newProgress.ZombiesLeft = 0;
            }

            if (newProgress.ZombiesLeft == 0)
            {
                newProgress.IsDestroyed = true;
            }

            _userZombiePackProgressSaver.SaveZombiePackProgress(userId, zombiePackId, newProgress);
            _userSaver.UpdateLastVisitedHotZone(userId, _zombiePackRetriever.GetHotZoneByZombiePackId(zombiePackId));
            
            int zombiesKilled = userAttackPower;
            if(newProgress.IsDestroyed == true)
            {
                zombiesKilled = progress.ZombiesLeft;
            }

            _userCountsSaver.AddZombiesKilled(userId, zombiesKilled);

            GiveUserArbitraryMoney(userId, zombiesKilled, newProgress);

            Guid hotZoneId = _zombiePackRetriever.GetHotZoneByZombiePackId(zombiePackId);
            if (_hotZoneRetriever.ZombiePacksLeft(userId, hotZoneId) == 0)
            {
                _userCountsSaver.AddHotZonesDestroyed(userId, 1);
            }

            if (newProgress.IsDestroyed == true)
            {
                _userCountsSaver.AddZombiePacksDestroyed(userId, 1);
                GiveMoneyReward(userId);
            }

            _userCountsSaver.RecordPeakZombiesDestroyed(userId, zombiesKilled);
            _userLevelService.CheckForLevelUp(userId);
        }
 private void GiveUserArbitraryMoney(Guid userId, int zombiesKilled, UserZombiePackProgress newProgress)
 {
     //after hunt is complete, user should get some arbitrary amount of money
     int moneyForHunt = zombiesKilled;
     _userSaver.AddMoney(userId, moneyForHunt);
     _userCountsSaver.AddMoney(userId, moneyForHunt);
 }