public CreateMimics_GS(Lobby lobby, RoundTracker roundTracker, TimeSpan?drawingTimeDuration = null) : base(lobby) { SelectivePromptUserState createMimics = new SelectivePromptUserState( usersToPrompt: lobby.GetAllUsers().Where((User user) => user != roundTracker.originalDrawer).ToList(), promptGenerator: (User user) => new UserPrompt() { UserPromptId = UserPromptId.Mimic_RecreateDrawing, Title = Constants.UIStrings.DrawingPromptTitle, Description = "Recreate the drawing you just saw to the best of your abilities", SubPrompts = new SubPrompt[] { new SubPrompt { Drawing = new DrawingPromptMetadata { ColorList = CommonConstants.DefaultColorPalette.ToList(), GalleryOptions = null } } }, SubmitButton = true }, formSubmitHandler: (User user, UserFormSubmission input) => { UserDrawing submission = new UserDrawing { Drawing = input.SubForms[0].Drawing, Owner = user }; roundTracker.UsersToUserDrawings.AddOrReplace(user, submission); return(true, string.Empty); }, exit: new WaitForUsers_StateExit( lobby: this.Lobby, waitingPromptGenerator: (User user) => (user == roundTracker.originalDrawer)?Prompts.DisplayText("Others are recreating your masterpiece. Enjoy the turmoil.")(user):Prompts.DisplayText("Waiting for others to finish mimicking.")(user) ), maxPromptDuration: drawingTimeDuration); this.Entrance.Transition(createMimics); createMimics.Transition(this.Exit); this.Legacy_UnityView = new Legacy_UnityView(this.Lobby) { ScreenId = new StaticAccessor <TVScreenId> { Value = TVScreenId.WaitForUserInputs }, Instructions = new StaticAccessor <string> { Value = "Recreate that drawing to the best of your abilities" }, }; }
public async Task <ActionResult <JsonResponse <string> > > UnshareWith(UserDrawing ud) { if (!await _authUtils.hasAccess(ud.Drawing.Id, HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value)) { return(Unauthorized()); } string id; try { id = await _drawingService.UnshareWithUserAsync(ud.Id); } catch (Exception) { return(new JsonResponse <string> { success = false, msg = "Unknown error unsharing with user" }); } return(new JsonResponse <string> { success = true, data = id }); }
public async Task <UserDrawing> ShareWithUserAsync(string email, string drawingId) { User user; try { user = await _context.Users.FirstAsync(u => u.Email == email); } catch (InvalidOperationException) { throw new KeyNotFoundException("Email not found"); } Drawing drawing; try { drawing = await _context.Drawings.Include(d => d.Owner).FirstAsync(d => d.Id == drawingId); } catch (InvalidOperationException) { throw new KeyNotFoundException("Drawing ID not found"); } if (drawing.Owner.Id == user.Id) { throw new InvalidOperationException("Cannot share with drawing owner"); } else if (await _context.UserDrawings.Where(ud => ud.User == user).Where(ud => ud.Drawing == drawing).AnyAsync()) { throw new InvalidOperationException("Drawing already shared with user"); } UserDrawing ud = new UserDrawing(); ud.Drawing = drawing; ud.User = user; await _context.UserDrawings.AddAsync(ud); await _context.SaveChangesAsync(); await UpdateLastModifiedAsync(drawing); return(ud); }
public DisplayOriginal_GS(Lobby lobby, TimeSpan?displayTimeDuration, UserDrawing displayDrawing) : base(lobby, stateTimeoutDuration: displayTimeDuration, exit: new WaitForStateTimeoutDuration_StateExit(waitingPromptGenerator: Prompts.DisplayText(Prompts.Text.LookAtTheScreen))) { this.Legacy_UnityView = new Legacy_UnityView(this.Lobby) { ScreenId = new StaticAccessor <TVScreenId> { Value = TVScreenId.ShowDrawings }, Title = new StaticAccessor <string> { Value = "Memorize this drawing" }, UnityImages = new StaticAccessor <IReadOnlyList <Legacy_UnityImage> > { Value = new List <Legacy_UnityImage>() { displayDrawing.GetUnityImage() } } }; this.Entrance.Transition(this.Exit); }
public async Task <ActionResult <JsonResponse <UserDrawing> > > ShareWith(UserDrawing ud) { if (!await _authUtils.hasAccess(ud.Drawing.Id, HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value)) { return(Unauthorized()); } try { ud = await _drawingService.ShareWithUserAsync(ud.User.Email, ud.Drawing.Id); } catch (Exception e) when(e is KeyNotFoundException || e is InvalidOperationException) { return(new JsonResponse <UserDrawing> { success = false, msg = e.Message }); } catch (Exception) { return(new JsonResponse <UserDrawing> { success = false, msg = "Unknown error sharing with user" }); } return(new JsonResponse <UserDrawing> { success = true, data = ud }); }
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); }