public void ShouldDoNothingGivenDuplicateBook()
    {
        Member member = MemberHelpers.CreateWithDefaultConstructor();
        Book   book   = BookHelpers.GetDefaultTestBook();

        member.AddBookRead(book);
        member.AddBookRead(book);

        // if we get to this point no error was thrown.
        Assert.Contains(book, member.BooksRead);
        Assert.Single(member.BooksRead !);
    }
        public void Returns100GivenPercentageOver100()
        {
            var member       = MemberHelpers.CreateWithDefaultConstructor();
            var subscription = SubscriptionHelpers.GetSubscriptionWithGivenSubscribedDaysToDateAndTotalSubscribedDays(731);

            member.AddSubscription(subscription.Dates);

            var expectedPercentage = 100;

            var percentage = _memberSubscriptionPeriodCalculationsService.GetPercentageProgressToAlumniStatus(member);

            Assert.Equal(expectedPercentage, percentage);
        }
        public void CalculatesCorrectPercentageGivenPercentageBelow100(int days)
        {
            var member       = MemberHelpers.CreateWithDefaultConstructor();
            var subscription = SubscriptionHelpers.GetSubscriptionWithGivenSubscribedDaysToDateAndTotalSubscribedDays(days);

            member.AddSubscription(subscription.Dates);

            var expectedPercentage = (int)(100 * ((double)days / (double)730));

            var percentage = _memberSubscriptionPeriodCalculationsService.GetPercentageProgressToAlumniStatus(member);

            Assert.Equal(expectedPercentage, percentage);
        }
Ejemplo n.º 4
0
        public void ReturnsProperMessageString()
        {
            Member member = MemberHelpers.CreateWithInternalConstructor();

            member.UpdateName("Steve", "Smith");

            MemberUpdatedEvent memberEvent = new MemberUpdatedEvent(member, "Links");

            var output   = DiscordLogMemberUpdateHandler.returnWebhookMessageString(memberEvent);
            var expected = $"User Steve Smith just updated their profile. Check it out here: https://devbetter.com/User/Details/TestUserId.";

            Assert.Equal(expected, output);
        }
Ejemplo n.º 5
0
    public void ShouldRemoveBookGivenBook()
    {
        Member member = MemberHelpers.CreateWithDefaultConstructor();
        Book   book   = BookHelpers.GetDefaultTestBook();

        member.AddBookRead(book);

        Assert.Contains(book, member.BooksRead);

        member.RemoveBookRead(book);

        Assert.Empty(member.BooksRead);
    }
    public void ShouldRemoveFavoriteArchiveVideoGivenExistingFavoriteArchiveVideo()
    {
        var member       = MemberHelpers.CreateWithInternalConstructor();
        var archiveVideo = new ArchiveVideo
        {
            Id = _validArchiveVideoId,
        };

        member.AddFavoriteArchiveVideo(archiveVideo);

        member.RemoveFavoriteArchiveVideo(archiveVideo);

        member.FavoriteArchiveVideos.Should().BeEmpty();
    }
    public void ShouldDoNothingGivenDuplicateArchiveVideo()
    {
        var member = MemberHelpers.CreateWithInternalConstructor();

        var archiveVideo = new ArchiveVideo
        {
            Id = _validArchiveVideoId,
        };

        member.AddFavoriteArchiveVideo(archiveVideo);
        member.AddFavoriteArchiveVideo(archiveVideo);

        member.FavoriteArchiveVideos.Count().Should().Be(1);
    }
    public void ReturnsInputYouTubeUrlIfContainsQuestionMark()
    {
        var member = MemberHelpers.CreateWithDefaultConstructor();

        string youtubeInput = "https://www.youtube.com/ardalis?";

        member.UpdateLinks(null, null, null, null, null, null, youtubeInput, null);

        MemberLinksDTO dto = MemberLinksDTO.FromMemberEntity(member);

        var result = dto.YouTubeUrl;

        Assert.Equal(youtubeInput, result);
    }
Ejemplo n.º 9
0
        private static void MongoInsert()
        {
            var members = MemberHelpers.GetRandomMongoMembers(100000);

            var time = System.Diagnostics.Stopwatch.StartNew();

            foreach (var member in members)
            {
                mongoService.InsertMember(member);
            }

            time.Stop();
            Console.WriteLine($"Tempo de Execução do Insert:{time.ElapsedMilliseconds}");
        }
    public void DoesNothingGivenNoCurrentSubscription()
    {
        Member             member = MemberHelpers.CreateWithDefaultConstructor();
        MemberSubscription starterSubscription = SubscriptionHelpers.GetSubscriptionWithPastEndDate();
        DateTime           newEndDate          = DateTime.Now.AddDays(30);
        var originalEndDate = starterSubscription.Dates.EndDate;

        member.AddSubscription(starterSubscription.Dates, 1);

        member.ExtendCurrentSubscription(newEndDate);

        Assert.Equal(originalEndDate, member.MemberSubscriptions[0].Dates.EndDate);

        Assert.Single(member.MemberSubscriptions);
    }
    public void ExtendsSubscription()
    {
        Member             member = MemberHelpers.CreateWithDefaultConstructor();
        MemberSubscription starterSubscription = SubscriptionHelpers.GetDefaultTestSubscription();
        DateTime           newEndDate          = DateTime.Now.AddDays(30);
        DateTime           originalStartDate   = starterSubscription.Dates.StartDate;

        member.AddSubscription(starterSubscription.Dates, 1);

        member.ExtendCurrentSubscription(newEndDate);

        Assert.Equal(newEndDate, member.MemberSubscriptions[0].Dates.EndDate);
        Assert.Equal(originalStartDate, member.MemberSubscriptions[0].Dates.StartDate);

        Assert.Single(member.MemberSubscriptions);
    }
Ejemplo n.º 12
0
        public void SelectOrdered(int[] inputIds, int numInputsWanted, int[] expectedIds)
        {
            TestUserManager.ResetTestUsers();
            List <UserCreatedObject> inputObjects = inputIds.Select(id => new UserCreatedObject()
            {
                Owner = TestUserManager.GetTestUser(id), Id = TestUserManager.GetTestUser(id).Id
            }).ToList();
            List <UserCreatedObject> expectedObjects = expectedIds.Select(id => new UserCreatedObject()
            {
                Owner = TestUserManager.GetTestUser(id), Id = TestUserManager.GetTestUser(id).Id
            }).ToList();

            List <UserCreatedObject> returnedObjects = MemberHelpers <UserCreatedObject> .Select_Ordered(inputObjects, numInputsWanted).ToList();

            Assert.IsTrue(returnedObjects.HasSameElements(expectedObjects), $"Expected:{string.Join(",", expectedObjects.Select(obj => obj.Owner.DisplayName))} Actual:{string.Join(",", returnedObjects.Select(obj => obj.Owner.DisplayName))}");
        }
    public void ShouldAddFavoriteArchiveVideoGivenArchiveVideo()
    {
        var member = MemberHelpers.CreateWithInternalConstructor();

        var archiveVideo = new ArchiveVideo
        {
            Id = _validArchiveVideoId,
        };

        member.AddFavoriteArchiveVideo(archiveVideo);

        using (new AssertionScope())
        {
            member.FavoriteArchiveVideos.Single().ArchiveVideoId.Should().Be(_validArchiveVideoId);
            member.FavoriteArchiveVideos.Single().MemberId.Should().Be(member.Id);
        }
    }
Ejemplo n.º 14
0
    private Member GetMemberWithDefaultLinks()
    {
        _initialBlogUrl = Guid.NewGuid().ToString();

        var member = MemberHelpers.CreateWithDefaultConstructor();

        member.UpdateLinks(_initialBlogUrl,
                           _initialCodinGameUrl,
                           _initialGitHubUrl,
                           _initialLinkedInUrl,
                           _initialOtherUrl,
                           _initialTwitchUrl,
                           _initialYouTubeUrl,
                           _initialTwitterUrl);
        member.Events.Clear();

        return(member);
    }
    public void AddsBillingActivityGivenMessageAndAmount()
    {
        Member  member = MemberHelpers.CreateWithDefaultConstructor();
        var     subscriptionPlanName = Guid.NewGuid().ToString();
        var     actionVerb           = BillingActivityVerb.None;
        var     random        = new Random();
        decimal amount        = random.Next() / 100;
        var     billingPeriod = BillingPeriod.Year;

        member.AddBillingActivity(subscriptionPlanName, actionVerb, billingPeriod, amount);

        var billingActivity = member.BillingActivities[0];

        using (new AssertionScope())
        {
            billingActivity.Details.BillingPeriod.Should().Be(billingPeriod);
            billingActivity.Details.Amount.Should().Be(amount);
        }
    }
    public void AddsBillingActivityGivenRequiredParameters()
    {
        Member member = MemberHelpers.CreateWithDefaultConstructor();
        var    subscriptionPlanName = Guid.NewGuid().ToString();
        var    actionVerb           = BillingActivityVerb.None;
        var    billingPeriod        = BillingPeriod.Month;

        member.AddBillingActivity(subscriptionPlanName, actionVerb, billingPeriod);

        var billingActivity = member.BillingActivities[0];

        using (new AssertionScope())
        {
            billingActivity.Details.SubscriptionPlanName.Should().Be(subscriptionPlanName);
            billingActivity.Details.ActionVerbPastTense.Should().Be(actionVerb);
            billingActivity.Details.BillingPeriod.Should().Be(billingPeriod);
            billingActivity.Details.MemberName.Should().Be(member.UserFullName());
        }
    }
Ejemplo n.º 17
0
        public void Assign(int[] inputIds, int duplicateCount, int groups, int maxPerGroup, bool allowDuplicateIds)
        {
            const int rerunCount = 100;
            Exception exc        = null;
            int       failCount  = 0;

            for (int i = 0; i < rerunCount; i++)
            {
                try
                {
                    TestUserManager.ResetTestUsers();
                    List <IConstraints <UserCreatedObject> > constraints = Enumerable.Range(0, groups)
                                                                           .Select(_ => new Constraints <UserCreatedObject>
                    {
                        AllowDuplicateIds = allowDuplicateIds,
                        MaxMemberCount    = maxPerGroup,
                    }).Cast <IConstraints <UserCreatedObject> >().ToList();
                    List <UserCreatedObject> inputObjects = inputIds.Select(id => new UserCreatedObject()
                    {
                        Owner = TestUserManager.GetTestUser(id), Id = TestUserManager.GetTestUser(id).Id
                    }).ToList();

                    List <IGroup <UserCreatedObject> > returnedObjects = MemberHelpers <UserCreatedObject> .Assign(constraints, inputObjects, duplicateCount).ToList();

                    Assert.AreEqual(groups, returnedObjects.Count());
                    if (inputIds.Length * duplicateCount > returnedObjects.Sum(group => group.Members.Count()))
                    {
                        Assert.IsTrue(returnedObjects.All(group => group.Members.Count() == maxPerGroup));
                    }
                    else
                    {
                        Assert.AreEqual(inputIds.Length * duplicateCount, returnedObjects.Sum(group => group.Members.Count()));
                        Assert.IsTrue(returnedObjects.All(group => group.Members.Count() <= maxPerGroup));
                    }
                }
                catch (Exception e)
                {
                    exc = e;
                    failCount++;
                }
            }
            Assert.AreEqual(0, failCount, message: $"Success rate ({rerunCount - failCount}/{rerunCount}) not 100%. Example Exception: {exc}");
        }
    public void ShouldDoNothingGivenFavoriteArchiveVideoNotInFavoriteArchiveVideos()
    {
        var member = MemberHelpers.CreateWithInternalConstructor();
        var existingArchiveVideo = new ArchiveVideo
        {
            Id = _validArchiveVideoId,
        };

        member.AddFavoriteArchiveVideo(existingArchiveVideo);
        int expectedCount = member.FavoriteArchiveVideos.Count();

        var nonexistingArchiveVideo = new ArchiveVideo
        {
            Id = _validArchiveVideoId + 1,
        };

        member.RemoveFavoriteArchiveVideo(nonexistingArchiveVideo);

        member.FavoriteArchiveVideos.Count().Should().Be(expectedCount);
    }
Ejemplo n.º 19
0
        private void AssignPrompts()
        {
            Stopwatch               stopwatch = Stopwatch.StartNew();
            IReadOnlyList <User>    users     = this.Lobby.GetAllUsers();
            List <ChallengeTracker> randomizedOrderChallenges = this.SubChallenges.Keys.OrderBy(_ => Rand.Next()).ToList();
            List <ChallengeTracker> excessChallenges          = randomizedOrderChallenges.Skip(this.NumRounds).ToList();

            randomizedOrderChallenges = randomizedOrderChallenges.Take(this.NumRounds).ToList();

            foreach (ChallengeTracker extra in excessChallenges)
            {
                this.SubChallenges.Remove(extra, out object _);
            }

            if (randomizedOrderChallenges.Count == 0)
            {
                throw new Exception("Can't play the game if there are no prompts");
            }

            List <IGroup <User> > groups = MemberHelpers <User> .Assign(
                randomizedOrderChallenges.Cast <IConstraints <User> >().ToList(),
                users,
                this.LayersPerTeam *this.TeamsPerPrompt);

            var assignments = groups.Zip(randomizedOrderChallenges);

            foreach ((IGroup <User> groupedUsers, ChallengeTracker tracker) in assignments)
            {
                int badCodingPractice = 0;
                tracker.UserSubmittedDrawings = groupedUsers.Members.ToDictionary((user) => user, (user) =>
                                                                                  new ChallengeTracker.TeamUserDrawing
                {
                    TeamId = Invariant($"{(badCodingPractice / LayersPerTeam)+1}"),
                    Color  = tracker.Colors[badCodingPractice++ % LayersPerTeam],
                    Owner  = user
                });
            }
            Debug.WriteLine(Invariant($"Assigned user prompts in ({stopwatch.ElapsedMilliseconds} ms)"), "Timing");
        }
Ejemplo n.º 20
0
        private static void CassandraInsert()
        {
            var config = new CassandraOptions();

            config.Url          = "localhost";
            config.DatabaseName = "MembersStore";

            var service = new JsonCassandraService(config);

            service.CreateTable();

            var members = MemberHelpers.GetRandomCassandraJsonMembers(100000);

            var time = System.Diagnostics.Stopwatch.StartNew();

            foreach (var member in members)
            {
                service.CreateAsync(member);
            }

            time.Stop();
            Console.WriteLine($"Tempo de Execução do Insert:{time.ElapsedMilliseconds}");
        }
Ejemplo n.º 21
0
    public void IsPrivateForDefaultConstructor()
    {
        var member = MemberHelpers.CreateWithDefaultConstructor();

        Assert.NotNull(member);
    }
Ejemplo n.º 22
0
    public void RequiresUserIdForInternalUsage()
    {
        var member = MemberHelpers.CreateWithInternalConstructor();

        Assert.Equal(MemberHelpers.TEST_USER_ID, member.UserId);
    }
Ejemplo n.º 23
0
    public void CreatesNoEventsWithDefaultConstructor()
    {
        var member = MemberHelpers.CreateWithDefaultConstructor();

        Assert.Empty(member.Events);
    }
Ejemplo n.º 24
0
        /// <summary>
        /// Dynamic fill model
        /// </summary>
        /// <typeparam name="T">Type of filling object.</typeparam>
        /// <param name="nodes">Items of FormCollection that are prepared for this model.</param>
        /// <param name="obj">Object for set values from items</param>
        private void DynamicFill <T>(IEnumerable <IFormTreeNode> nodes, T obj)
        {
            if (obj is IDynamicFillModel dynamicFillModel)
            {
                dynamicFillModel.DynamicFill(nodes, Converter);
                return;
            }

            if (!(obj is IDynamicFillModeController dynamicFillModeController))
            {
                dynamicFillModeController = null;
            }

            dynamicFillModeController?.OnStartFillModel(nodes);

            foreach (var node in nodes)
            {
                // Simple property
                if (node is FormTreeNode fte)
                {
                    // Search fields
                    var(member, declaringType) = MemberHelpers.GetPropertyField(obj, fte.Key);

                    // If FormCollection have other system fields
                    if (member == null)
                    {
                        continue;
                    }
                    dynamicFillModeController?.OnBeforeSetPropertyValue(node, fte.Key, fte.Value);
                    AutoSetValueMember(obj, fte.Key, member, declaringType, fte.Value, Converter);
                }
                // Properties collection
                else if (node is FormTreeCollection ftc)
                {
                    // Search fields
                    var(member, declaringType) = MemberHelpers.GetPropertyField(obj, node.Key);

                    // If FormCollection have other system fields
                    if (member == null)
                    {
                        continue;
                    }

                    object includedModel = null;
                    if (member is FieldInfo field)
                    {
                        includedModel = field.GetValue(obj);
                        if (includedModel == null)
                        {
                            includedModel = Activator.CreateInstance(field.FieldType);
                        }
                        dynamicFillModeController?.OnBeforeSetPropertyValue(node, node.Key, includedModel);
                        field.SetValue(obj, includedModel);
                    }
                    else if (member is PropertyInfo property)
                    {
                        includedModel = property.GetValue(obj);
                        if (includedModel == null)
                        {
                            includedModel = Activator.CreateInstance(property.PropertyType);
                        }
                        dynamicFillModeController?.OnBeforeSetPropertyValue(node, node.Key, includedModel);
                        property.SetValue(obj, includedModel);
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }

                    if (includedModel is IDynamicFillModel dynamicCollection)
                    {
                        dynamicCollection.DynamicFill(ftc.Childs, Converter);
                    }
                    else
                    {
                        DynamicFill(ftc.Childs, includedModel);
                    }
                    //TODO: No implement Array, List, and other IEnumerable class
                }
            }
            dynamicFillModeController?.OnFinishFillModel(nodes.Select(x => x.Key).ToArray());
        }
Ejemplo n.º 25
0
        public FriendQuizGameMode(Lobby lobby, List <ConfigureLobbyRequest.GameModeOptionRequest> gameModeOptions, StandardGameModeOptions standardOptions)
        {
            GameDuration duration = standardOptions.GameDuration;
            double       questionPoolMultiplier = 2.5; // Question pool is X times bigger than number of questions per person.

            int numQuestionsToAnswer = (int)gameModeOptions[(int)GameModeOptionsEnum.NumAnswerQuestions].ValueParsed;
            int numRounds            = Math.Min(lobby.GetAllUsers().Count(), FriendQuizConstants.MaxUserRounds[duration]);
            int numQuestionSetup     = (int)(numQuestionsToAnswer * questionPoolMultiplier / numRounds) + 1; // How many questions each user should contribute.

            TimeSpan?setupTimer     = null;
            TimeSpan?answeringTimer = null;
            TimeSpan?votingTimer    = null;

            if (standardOptions.TimerEnabled)
            {
                setupTimer     = FriendQuizConstants.SetupTimer[duration];
                answeringTimer = FriendQuizConstants.AnsweringTimer[duration];
                votingTimer    = FriendQuizConstants.VotingTimer[duration];
            }

            Dictionary <User, List <Question> > usersToAssignedQuestions = new Dictionary <User, List <Question> >();
            int maxNumAssigned = 1; // Variable for tracking user with most questions.

            StateChain gameStateChain = new StateChain(stateGenerator: (int counter) =>
            {
                if (counter == 0)
                {
                    setupTimer = setupTimer?.Multiply(numQuestionSetup);
                    return(new Setup_GS(
                               lobby: lobby,
                               roundTracker: RoundTracker,
                               numExpectedPerUser: numQuestionSetup,
                               setupDuration: setupTimer));
                }
                else if (counter == 1)
                {
                    List <UserQuestionsHolder> userQuestionsHolders = lobby.GetAllUsers().Select(user => new UserQuestionsHolder(user, numQuestionsToAnswer)).ToList();
                    List <Question> randomizedQuestions             = RoundTracker.Questions.OrderBy(_ => Rand.Next()).ToList();
                    List <IGroup <Question> > assignments           = MemberHelpers <Question> .Assign(userQuestionsHolders.Cast <IConstraints <Question> >().ToList(), randomizedQuestions, lobby.GetAllUsers().Count);

                    var pairings = userQuestionsHolders.Zip(assignments);

                    foreach ((UserQuestionsHolder holder, IGroup <Question> questions) in pairings)
                    {
                        if (questions.Members.Count() > maxNumAssigned)
                        {
                            maxNumAssigned = questions.Members.Count();
                        }
                        // Makes a copy of the questions so that it can handle multiple people answering the same question without them both overriding the same object
                        usersToAssignedQuestions.Add(holder.QuestionedUser, questions.Members.Select(question => new Question(question)
                        {
                            MainUser = holder.QuestionedUser
                        }).ToList());
                    }

                    answeringTimer = answeringTimer?.Multiply(maxNumAssigned);

                    return(new AnswerQuestion_GS(
                               lobby: lobby,
                               usersToAssignedQuestions: usersToAssignedQuestions,
                               answerTimeDuration: answeringTimer));
                }
                else if (counter == 2)
                {
                    votingTimer = votingTimer?.Multiply(maxNumAssigned);

                    List <User> randomizedUsers = usersToAssignedQuestions.Keys
                                                  .OrderBy(_ => Rand.Next())
                                                  .ToList()        // Probably not needed, but just in case.
                                                  .Take(numRounds) // Number of rounds is limited based on game duration.
                                                  .ToList();

                    return(GetUserQueryStateChain(randomizedUsers));
                }
                else
                {
                    return(null);
                }
            });


            this.Entrance.Transition(gameStateChain);
            gameStateChain.Transition(this.Exit);

            StateChain GetUserQueryStateChain(List <User> users)
            {
                List <State> chain = new List <State>();

                foreach (User user in users)
                {
                    List <Question> nonAbstainedQuestions = usersToAssignedQuestions[user].Where(question => !question.Abstained).ToList();
                    if (nonAbstainedQuestions.Count > 0)
                    {
                        chain.Add(new StateChain(stateGenerator: (int counter) =>
                        {
                            if (counter == 0)
                            {
                                return(new SliderQueryAndReveal(
                                           lobby: lobby,
                                           objectsToQuery: nonAbstainedQuestions,
                                           usersToQuery: lobby.GetAllUsers().Where(lobbyUser => lobbyUser != user).ToList(),
                                           queryTime: votingTimer)
                                {
                                    QueryPromptTitle = $"How do you think {user.DisplayName} answered these questions?",
                                    QueryPromptDescription = "The tighter the range of your guess, the more points if you're correct",
                                    QueryViewOverrides = new UnityViewOverrides()
                                    {
                                        Title = $"How do you think {user.DisplayName} answered these questions?",
                                    },
                                    RevealViewOverrides = new UnityViewOverrides()
                                    {
                                        Title = $"This is how {user.DisplayName} answered those questions.",
                                    },
                                    QueryExitListener = CountQueries,
                                });
                            }
                            else if (counter == 1)
                            {
                                if (user == users.Last())
                                {
                                    return(new ScoreBoardGameState(lobby, "Final Scores"));
                                }
                                else
                                {
                                    return(new ScoreBoardGameState(lobby));
                                }
                            }
                            else
                            {
                                return(null);
                            }
                        }));
                    }
                }
                return(new StateChain(chain));
            }
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Check present key in elements.
        /// </summary>
        /// <param name="key">Search key.</param>
        /// <returns></returns>
        public bool HasKey(TKey key)
        {
            var fieldName = MemberHelpers.GetKeyPropertyFieldName <TElement>();

            return(HasKey(key, fieldName));
        }
Ejemplo n.º 27
0
 /// <summary>
 /// Gets the value associated with the specified key.
 /// </summary>
 /// <param name="key">The key of the value to get.</param>
 /// <returns> The value associated with the specified key. If the specified key is not found,
 /// a get operation throws a System.Collections.Generic.KeyNotFoundException, and
 /// a set operation creates a new element with the specified key.</returns>
 public TElement this[TKey key] {
     get {
         var fieldName = MemberHelpers.GetKeyPropertyFieldName <TElement>();
         return(elements.First(x => Equals(x.GetValue <TKey>(fieldName), key)));
     }
 }
        public BattleReadyGameMode(Lobby lobby, List <ConfigureLobbyRequest.GameModeOptionRequest> gameModeOptions, StandardGameModeOptions standardOptions)
        {
            GameDuration duration = standardOptions.GameDuration;

            this.Lobby = lobby;
            int numRounds  = BattleReadyConstants.NumRounds[duration];
            int numPlayers = lobby.GetAllUsers().Count();

            TimeSpan?setupDrawingTimer = null;
            TimeSpan?setupPromptTimer  = null;
            TimeSpan?creationTimer     = null;
            TimeSpan?votingTimer       = null;

            int numOfEachPartInHand = (int)gameModeOptions[(int)GameModeOptionsEnum.NumEachPartInHand].ValueParsed;

            int numPromptsPerRound  = Math.Min(numPlayers, BattleReadyConstants.MaxNumSubRounds[duration]);
            int minDrawingsRequired = numOfEachPartInHand * 3; // the amount to make one playerHand to give everyone

            int expectedPromptsPerUser  = (int)Math.Ceiling(1.0 * numPromptsPerRound * numRounds / lobby.GetAllUsers().Count);
            int expectedDrawingsPerUser = Math.Max((minDrawingsRequired / numPlayers + 1) * 2, BattleReadyConstants.NumDrawingsPerPlayer[duration]);

            if (standardOptions.TimerEnabled)
            {
                setupDrawingTimer = BattleReadyConstants.SetupPerDrawingTimer[duration];
                setupPromptTimer  = BattleReadyConstants.SetupPerPromptTimer[duration];
                creationTimer     = BattleReadyConstants.PerCreationTimer[duration];
                votingTimer       = BattleReadyConstants.VotingTimer[duration];
            }

            SetupDrawings_GS setupDrawing = new SetupDrawings_GS(
                lobby: lobby,
                drawings: this.Drawings,
                numExpectedPerUser: expectedDrawingsPerUser,
                setupDurration: setupDrawingTimer * expectedDrawingsPerUser);

            SetupPrompts_GS setupPrompt = new SetupPrompts_GS(
                lobby: lobby,
                prompts: Prompts,
                numExpectedPerUser: expectedPromptsPerUser,
                setupDuration: setupPromptTimer);

            List <Prompt> battlePrompts = new List <Prompt>();
            IReadOnlyList <PeopleUserDrawing> headDrawings = new List <PeopleUserDrawing>();
            IReadOnlyList <PeopleUserDrawing> bodyDrawings = new List <PeopleUserDrawing>();
            IReadOnlyList <PeopleUserDrawing> legsDrawings = new List <PeopleUserDrawing>();

            setupDrawing.AddExitListener(() =>
            {
                // Trim extra prompts/drawings.
                headDrawings = Drawings.ToList().FindAll((drawing) => drawing.Type == BodyPartType.Head);
                bodyDrawings = Drawings.ToList().FindAll((drawing) => drawing.Type == BodyPartType.Body);
                legsDrawings = Drawings.ToList().FindAll((drawing) => drawing.Type == BodyPartType.Legs);
            });
            int numPromptsPerUserPerRound = 0; // Set during below exit listener.

            setupPrompt.AddExitListener(() =>
            {
                battlePrompts      = MemberHelpers <Prompt> .Select_Ordered(Prompts.OrderBy(prompt => prompt.CreationTime).ToList(), numPromptsPerRound * numRounds);
                numRounds          = (battlePrompts.Count - 1) / numPromptsPerRound + 1;
                numPromptsPerRound = (int)Math.Ceiling(1.0 * battlePrompts.Count / numRounds);

                numPromptsPerUserPerRound = Math.Max(1, numPromptsPerRound / 2);
                int maxNumUsersPerPrompt  = Math.Min(12, (int)Math.Ceiling(1.0 * numPlayers * numPromptsPerUserPerRound / numPromptsPerRound));

                foreach (Prompt prompt in battlePrompts)
                {
                    prompt.MaxMemberCount = maxNumUsersPerPrompt;
                }
            });

            List <GameState> creationGameStates     = new List <GameState>();
            List <GameState> votingGameStates       = new List <GameState>();
            List <GameState> voteRevealedGameStates = new List <GameState>();
            List <GameState> scoreboardGameStates   = new List <GameState>();

            int countRounds = 0;

            #region GameState Generators
            GameState CreateContestantCreationGamestate()
            {
                RoundTracker.ResetRoundVariables();
                List <Prompt> prompts = battlePrompts.Take(numPromptsPerRound).ToList();

                battlePrompts.RemoveRange(0, prompts.Count);

                List <IGroup <User> > assignments = MemberHelpers <User> .Assign(
                    prompts.Cast <IConstraints <User> >().ToList(),
                    lobby.GetAllUsers().ToList(),
                    duplicateMembers : (int)Math.Ceiling((1.0 * prompts.Count / numPromptsPerRound) * numPromptsPerUserPerRound));

                var pairings = prompts.Zip(assignments);

                foreach ((Prompt prompt, IGroup <User> users) in pairings)
                {
                    foreach (User user in users.Members)
                    {
                        prompt.UsersToUserHands.TryAdd(user, new Prompt.UserHand
                        {
                            // Users have even probabilities regardless of how many drawings they submitted.
                            HeadChoices = MemberHelpers <PeopleUserDrawing> .Select_DynamicWeightedRandom(headDrawings, numOfEachPartInHand),
                            BodyChoices = MemberHelpers <PeopleUserDrawing> .Select_DynamicWeightedRandom(bodyDrawings, numOfEachPartInHand),
                            LegChoices  = MemberHelpers <PeopleUserDrawing> .Select_DynamicWeightedRandom(legsDrawings, numOfEachPartInHand),
                            Owner       = user
                        });

                        if (!RoundTracker.UsersToAssignedPrompts.ContainsKey(user))
                        {
                            RoundTracker.UsersToAssignedPrompts.Add(user, new List <Prompt>());
                        }
                        RoundTracker.UsersToAssignedPrompts[user].Add(prompt);
                    }
                }

                GameState toReturn = new ContestantCreation_GS(
                    lobby: lobby,
                    roundTracker: RoundTracker,
                    creationDuration: creationTimer);

                toReturn.Transition(CreateVotingGameStates(prompts));
                return(toReturn);
            }

            Func <StateChain> CreateVotingGameStates(List <Prompt> roundPrompts)
            {
                return(() =>
                {
                    StateChain voting = new StateChain(
                        stateGenerator: (int counter) =>
                    {
                        if (counter < roundPrompts.Count)
                        {
                            Prompt roundPrompt = roundPrompts[counter];

                            return GetVotingAndRevealState(roundPrompt, votingTimer);
                        }
                        else
                        {
                            // Stops the chain.
                            return null;
                        }
                    });
                    voting.Transition(CreateScoreGameState(roundPrompts));
                    return voting;
                });
            }

            Func <GameState> CreateScoreGameState(List <Prompt> roundPrompts)
            {
                return(() =>
                {
                    List <Person> winnersPeople = roundPrompts.Select((prompt) => (Person)prompt.UsersToUserHands[prompt.Winner]).ToList();

                    countRounds++;
                    GameState displayPeople = new DisplayPeople_GS(
                        lobby: lobby,
                        title: "Here are your winners",
                        peopleList: winnersPeople,
                        imageTitle: (person) => roundPrompts[winnersPeople.IndexOf(person)].Text,
                        imageHeader: (person) => person.Name
                        );

                    if (battlePrompts.Count <= 0)
                    {
                        GameState finalScoreBoard = new ScoreBoardGameState(
                            lobby: lobby,
                            title: "Final Scores");
                        displayPeople.Transition(finalScoreBoard);
                        finalScoreBoard.Transition(this.Exit);
                    }
                    else
                    {
                        GameState scoreBoard = new ScoreBoardGameState(
                            lobby: lobby);
                        displayPeople.Transition(scoreBoard);
                        scoreBoard.Transition(CreateContestantCreationGamestate);
                    }
                    return displayPeople;
                });
            }

            #endregion

            this.Entrance.Transition(setupDrawing);
            setupDrawing.Transition(setupPrompt);
            setupPrompt.Transition(CreateContestantCreationGamestate);
        }