public TwoToneDrawingGameMode(Lobby lobby, List <ConfigureLobbyRequest.GameModeOptionRequest> gameModeOptions, StandardGameModeOptions standardOptions) { this.Lobby = lobby; GameDuration duration = standardOptions.GameDuration; int maxPossibleTeamCount = 8; // Can go higher than this in extreme circumstances. bool useSingleColor = (bool)gameModeOptions[(int)GameModeOptionsEnum.useSingleColor].ValueParsed; int numLayers = (int)gameModeOptions[(int)GameModeOptionsEnum.numLayers].ValueParsed; int numPlayers = lobby.GetAllUsers().Count(); if (numLayers * 2 > numPlayers) { numLayers = numPlayers / 2; } int numRounds = Math.Min(TwoToneDrawingConstants.MaxNumRounds[duration], numPlayers); int numDrawingsPerPlayer = Math.Min(TwoToneDrawingConstants.DrawingsPerPlayer[duration], numRounds); int numTeamsLowerBound = Math.Max(2, 1 * numPlayers / (numRounds * numLayers)); // Lower bound. int numTeamsUpperBound = Math.Min(maxPossibleTeamCount, numDrawingsPerPlayer * numPlayers / (numRounds * numLayers)); // Upper bound. int numTeams = Math.Max(numTeamsLowerBound, numTeamsUpperBound); // Possible for lower bound to be higher than upper bound. that is okay. //int drawingsPerPlayer = numRounds * numLayers * numTeams / numPlayers; TimeSpan?setupTimer = null; TimeSpan?drawingTimer = null; TimeSpan?votingTimer = null; if (standardOptions.TimerEnabled) { setupTimer = TwoToneDrawingConstants.SetupTimer[duration]; drawingTimer = TwoToneDrawingConstants.PerDrawingTimer[duration].MultipliedBy(numDrawingsPerPlayer); votingTimer = TwoToneDrawingConstants.VotingTimer[duration]; } Setup = new Setup_GS( lobby: lobby, challengeTrackers: this.SubChallenges, useSingleColor: useSingleColor, numLayersPerTeam: numLayers, numTeamsPerPrompt: numTeams, numRounds: numRounds, setupTimer: setupTimer, drawingTimer: drawingTimer); StateChain GamePlayLoopGenerator() { List <ChallengeTracker> challenges = SubChallenges.Keys.OrderBy(_ => Rand.Next()).ToList(); StateChain chain = new StateChain( stateGenerator: (int counter) => { if (counter < challenges.Count) { return(new StateChain(stateGenerator: (int i) => { switch (i) { case 0: return GetVotingAndRevealState(challenges[counter], votingTimer); case 1: return ((counter == challenges.Count - 1) ? new ScoreBoardGameState(lobby, "Final Scores") : new ScoreBoardGameState(lobby)); default: return null; } })); } else { return(null); } }); chain.Transition(this.Exit); return(chain); } Setup.Transition(GamePlayLoopGenerator); this.Entrance.Transition(Setup); }
public ImposterDrawingGameMode(Lobby lobby, List <ConfigureLobbyRequest.GameModeOptionRequest> gameModeOptions, StandardGameModeOptions standardOptions) { this.Lobby = lobby; TimeSpan? writingTimer = null; TimeSpan? drawingTimer = null; TimeSpan? votingTimer = null; GameDuration duration = standardOptions.GameDuration; if (standardOptions.TimerEnabled) { writingTimer = ImposterDrawingConstants.WritingTimer[duration]; drawingTimer = ImposterDrawingConstants.DrawingTimer[duration]; votingTimer = ImposterDrawingConstants.VotingTimer[duration]; } List <Prompt> prompts = new List <Prompt>(); int numRounds = Math.Min(ImposterDrawingConstants.MaxNumRounds[duration], this.Lobby.GetAllUsers().Count); int numDrawingsPerUser = Math.Min(ImposterDrawingConstants.MaxDrawingsPerPlayer[duration], numRounds - 1); numRounds = Math.Min(numRounds, (this.Lobby.GetAllUsers().Count - 1) * numDrawingsPerUser / ImposterDrawingConstants.MinNumPlayersPerRound); int playersPerPrompt = Math.Min(ImposterDrawingConstants.MaxNumPlayersPerRound, this.Lobby.GetAllUsers().Count - 1); playersPerPrompt = Math.Min(playersPerPrompt, this.Lobby.GetAllUsers().Count *numDrawingsPerUser / numRounds + 1); Setup = new Setup_GS( lobby: lobby, promptsToPopulate: prompts, writingTimeDuration: writingTimer, drawingTimeDuration: drawingTimer, numDrawingsPerUser: numDrawingsPerUser, numRounds: numRounds, maxPlayersPerPrompt: playersPerPrompt); StateChain CreateGamePlayLoop() { List <State> stateList = new List <State>(); foreach (Prompt prompt in prompts) { stateList.Add(GetImposterLoop(prompt, prompt == prompts.Last())); } StateChain gamePlayChain = new StateChain(states: stateList); gamePlayChain.Transition(this.Exit); return(gamePlayChain); } this.Entrance.Transition(Setup); Setup.Transition(CreateGamePlayLoop); StateChain GetImposterLoop(Prompt prompt, bool lastRound = false) { return(new StateChain( stateGenerator: (int counter) => { if (counter == 0) { return GetVotingAndRevealState(prompt, (prompt.UsersToDrawings.Values.Any(val => val == null)), votingTimer); } if (counter == 1) { if (lastRound) { return new ScoreBoardGameState(lobby, "Final Scores"); } else { return new ScoreBoardGameState(lobby); } } else { return null; } })); } }
public MimicGameMode(Lobby lobby, List <ConfigureLobbyRequest.GameModeOptionRequest> gameModeOptions, StandardGameModeOptions standardOptions) { GameDuration duration = standardOptions.GameDuration; int numStartingDrawingsPerUser = 1; int maxDrawingsBeforeVoteInput = (int)gameModeOptions[(int)GameModeOptions.MaxDrawingsBeforeVote].ValueParsed; int maxVoteDrawings = 12; // Everybody's drawing should show up, but it gets a little prohibitive past 12 so limit it here. TimeSpan? drawingTimer = null; TimeSpan? votingTimer = null; if (standardOptions.TimerEnabled) { drawingTimer = MimicConstants.DrawingTimer[duration]; votingTimer = MimicConstants.VotingTimer[duration]; } TimeSpan?extendedDrawingTimer = drawingTimer.MultipliedBy(MimicConstants.MimicTimerMultiplier); int numPlayers = lobby.GetAllUsers().Count(); int numRounds = Math.Min(MimicConstants.MaxRounds[duration], numPlayers); this.Lobby = lobby; Setup = new Setup_GS( lobby: lobby, drawings: Drawings, numDrawingsPerUser: numStartingDrawingsPerUser, drawingTimeDuration: drawingTimer); List <UserDrawing> randomizedDrawings = new List <UserDrawing>(); Setup.AddExitListener(() => { randomizedDrawings = this.Drawings .OrderBy(_ => Rand.Next()) .ToList() .Take(numRounds) // Limit number of rounds based on game duration. .ToList(); }); StateChain CreateGamePlayLoop() { bool timeToShowScores = true; StateChain gamePlayLoop = new StateChain(stateGenerator: (int counter) => { if (randomizedDrawings.Count > 0) { StateChain CreateMultiRoundLoop() { int maxDrawingsBeforeVote = Math.Min(maxDrawingsBeforeVoteInput, randomizedDrawings.Count); if (randomizedDrawings.Count == 0) { throw new Exception("Something went wrong while setting up the game"); } List <RoundTracker> roundTrackers = new List <RoundTracker>(); return(new StateChain(stateGenerator: (int counter) => { if (counter < maxDrawingsBeforeVote) { UserDrawing originalDrawing = randomizedDrawings.First(); randomizedDrawings.RemoveAt(0); RoundTracker drawingsRoundTracker = new RoundTracker(); roundTrackers.Add(drawingsRoundTracker); drawingsRoundTracker.originalDrawer = originalDrawing.Owner; drawingsRoundTracker.UsersToUserDrawings.AddOrUpdate(originalDrawing.Owner, originalDrawing, (User user, UserDrawing drawing) => originalDrawing); DisplayOriginal_GS displayGS = new DisplayOriginal_GS( lobby: lobby, displayTimeDuration: MimicConstants.MemorizeTimerLength, displayDrawing: originalDrawing); CreateMimics_GS mimicsGS = new CreateMimics_GS( lobby: lobby, roundTracker: drawingsRoundTracker, drawingTimeDuration: extendedDrawingTimer ); mimicsGS.AddExitListener(() => { List <User> randomizedUsersToDisplay = new List <User>(); List <User> randomizedKeys = drawingsRoundTracker.UsersToUserDrawings.Keys.OrderBy(_ => Rand.Next()).ToList(); for (int i = 0; i < maxVoteDrawings && i < randomizedKeys.Count; i++) { randomizedUsersToDisplay.Add(randomizedKeys[i]); } if (!randomizedUsersToDisplay.Contains(drawingsRoundTracker.originalDrawer)) { randomizedUsersToDisplay.RemoveAt(0); randomizedUsersToDisplay.Add(drawingsRoundTracker.originalDrawer); } randomizedUsersToDisplay = randomizedUsersToDisplay.OrderBy(_ => Rand.Next()).ToList(); drawingsRoundTracker.UsersToDisplay = randomizedUsersToDisplay; }); return new StateChain(states: new List <State>() { displayGS, mimicsGS }, exit: null); } else if (counter < maxDrawingsBeforeVote * 2) { return GetVotingAndRevealState(roundTrackers[counter - maxDrawingsBeforeVote], votingTimer); } else { return null; } })); } return(CreateMultiRoundLoop()); } else { if (timeToShowScores) { timeToShowScores = false; return(new ScoreBoardGameState( lobby: lobby, title: "Final Scores")); } else { //Ends the chain return(null); } } }); gamePlayLoop.Transition(this.Exit); return(gamePlayLoop); } this.Entrance.Transition(Setup); Setup.Transition(CreateGamePlayLoop); }