private async Task ProcessPickupsForLeagueYear(LeagueYear leagueYear) { var allActiveBids = await GetActiveBids(leagueYear); if (!allActiveBids.Any()) { return; } LeagueWideValues leagueWideValues = await GetLeagueWideValues(); var insufficientFundsBids = allActiveBids.Where(x => x.BidAmount > x.Publisher.Budget); var winnableBids = GetWinnableBids(allActiveBids, leagueYear.Options, leagueWideValues); var winningBids = GetWinningBids(winnableBids); var takenGames = winningBids.Select(x => x.MasterGame); var losingBids = allActiveBids .Except(winningBids) .Except(insufficientFundsBids) .Where(x => takenGames.Contains(x.MasterGame)) .Select(x => new FailedPickupBid(x, "Publisher was outbid.")); var insufficientFundsBidFailures = insufficientFundsBids.Select(x => new FailedPickupBid(x, "Not enough budget.")); var failedBids = losingBids.Concat(insufficientFundsBidFailures); await ProcessSuccessfulAndFailedBids(winningBids, failedBids); //When we are done, we run again. //This will repeat until there are no active bids. await Task.Delay(5); await ProcessPickupsForLeagueYear(leagueYear); }
public decimal GetProjectedPointsForGame(PublisherGame publisherGame, LeagueWideValues leagueWideValues) { if (publisherGame.FantasyPoints.HasValue) { return(publisherGame.FantasyPoints.Value); } return(GetPointsForScore(publisherGame, null, leagueWideValues)); }
public StandingViewModel(Publisher publisher, ScoringSystem scoringSystem, LeagueWideValues leagueWideValues) { PublisherID = publisher.PublisherID; LeagueID = publisher.League.LeagueID; PublisherName = publisher.PublisherName; LeagueName = publisher.League.LeagueName; PlayerName = publisher.User.UserName; Year = publisher.Year; TotalFantasyPoints = publisher.TotalFantasyPoints; ProjectedFantasyPoints = publisher.GetProjectedFantasyPoints(scoringSystem, leagueWideValues); }
public async Task <IActionResult> GetLeagueYear(Guid leagueID, int year) { Maybe <LeagueYear> leagueYear = await _fantasyCriticService.GetLeagueYear(leagueID, year); if (leagueYear.HasNoValue) { throw new Exception("Something went really wrong, no options are set up for this league."); } var currentUser = await _userManager.FindByNameAsync(User.Identity.Name); var usersInLeague = await _fantasyCriticService.GetUsersInLeague(leagueYear.Value.League); bool userIsInLeague = usersInLeague.Any(x => x.UserID == currentUser.UserID); var inviteesToLeague = await _fantasyCriticService.GetOutstandingInvitees(leagueYear.Value.League); bool userIsInvitedToLeague = inviteesToLeague.Any(x => x == currentUser.EmailAddress); if (!userIsInLeague && !userIsInvitedToLeague) { return(Unauthorized()); } var publishersInLeague = await _fantasyCriticService.GetPublishersInLeagueForYear(leagueYear.Value.League, leagueYear.Value.Year); var supportedYear = (await _fantasyCriticService.GetSupportedYears()).SingleOrDefault(x => x.Year == year); if (supportedYear is null) { return(BadRequest()); } StartDraftResult startDraftResult = await _fantasyCriticService.GetStartDraftResult(leagueYear.Value, publishersInLeague, usersInLeague); Maybe <Publisher> nextDraftPublisher = await _fantasyCriticService.GetNextDraftPublisher(leagueYear.Value); DraftPhase draftPhase = await _fantasyCriticService.GetDraftPhase(leagueYear.Value); var userPublisher = publishersInLeague.SingleOrDefault(x => x.User.UserID == currentUser.UserID); IReadOnlyList <PublisherGame> availableCounterPicks = new List <PublisherGame>(); if (nextDraftPublisher.HasValue) { availableCounterPicks = await _fantasyCriticService.GetAvailableCounterPicks(leagueYear.Value, nextDraftPublisher.Value); } LeagueWideValues leagueWideValues = await _fantasyCriticService.GetLeagueWideValues(); var leagueViewModel = new LeagueYearViewModel(leagueYear.Value, supportedYear, publishersInLeague, currentUser, userPublisher, _clock, leagueYear.Value.PlayStatus, startDraftResult, usersInLeague, nextDraftPublisher, draftPhase, availableCounterPicks, leagueWideValues); return(Ok(leagueViewModel)); }
public async Task UpdateFantasyPoints(LeagueYear leagueYear) { Dictionary <Guid, decimal?> publisherGameScores = new Dictionary <Guid, decimal?>(); LeagueWideValues leagueWideValues = await GetLeagueWideValues(); var publishersInLeague = await GetPublishersInLeagueForYear(leagueYear.League, leagueYear.Year); foreach (var publisher in publishersInLeague) { foreach (var publisherGame in publisher.PublisherGames) { decimal?fantasyPoints = leagueYear.Options.ScoringSystem.GetPointsForGame(publisherGame, _clock, leagueWideValues); publisherGameScores.Add(publisherGame.PublisherGameID, fantasyPoints); } } await _fantasyCriticRepo.UpdateFantasyPoints(publisherGameScores); }
protected abstract decimal GetPointsForScore(PublisherGame publisherGame, decimal?criticScore, LeagueWideValues leagueWideValues);
protected abstract decimal?GetPointsInternal(PublisherGame publisherGame, IClock clock, LeagueWideValues leagueWideValues);
public decimal?GetPointsForGame(PublisherGame publisherGame, IClock clock, LeagueWideValues leagueWideValues) { return(GetPointsInternal(publisherGame, clock, leagueWideValues)); }
protected override decimal GetPointsForScore(PublisherGame publisherGame, decimal?criticScore, LeagueWideValues leagueWideValues) { if (criticScore.HasValue) { decimal fantasyPoints = 0m; decimal criticPointsOver90 = (criticScore.Value - 90); if (criticPointsOver90 > 0) { fantasyPoints += criticPointsOver90; } decimal criticPointsOver70 = (criticScore.Value - 70); fantasyPoints += criticPointsOver70; if (publisherGame.CounterPick) { fantasyPoints *= -1; } return(fantasyPoints); } if (publisherGame.CounterPick) { return(leagueWideValues.AverageCounterPickPoints); } return(leagueWideValues.AverageStandardGamePoints); }
protected override decimal?GetPointsInternal(PublisherGame publisherGame, IClock clock, LeagueWideValues leagueWideValues) { if (publisherGame.MasterGame.HasNoValue) { return(null); } if (!publisherGame.WillRelease()) { return(0m); } if (!publisherGame.MasterGame.Value.MasterGame.IsReleased(clock)) { return(null); } decimal?possibleManualScore = publisherGame.ManualCriticScore; if (possibleManualScore.HasValue) { return(GetPointsForScore(publisherGame, possibleManualScore.Value, leagueWideValues)); } decimal?possibleCriticScore = publisherGame.MasterGame.Value.MasterGame.CriticScore; if (!possibleCriticScore.HasValue) { return(0m); } return(GetPointsForScore(publisherGame, possibleCriticScore.Value, leagueWideValues)); }
public LeagueYearViewModel(LeagueYear leagueYear, SupportedYear supportedYear, IEnumerable <Publisher> publishers, FantasyCriticUser currentUser, Publisher userPublisher, IClock clock, PlayStatus playStatus, StartDraftResult startDraftResult, IEnumerable <FantasyCriticUser> users, Maybe <Publisher> nextDraftPublisher, DraftPhase draftPhase, IEnumerable <PublisherGame> availableCounterPicks, LeagueWideValues leagueWideValues) { LeagueID = leagueYear.League.LeagueID; Year = leagueYear.Year; SupportedYear = new SupportedYearViewModel(supportedYear); StandardGames = leagueYear.Options.StandardGames; GamesToDraft = leagueYear.Options.GamesToDraft; CounterPicks = leagueYear.Options.CounterPicks; MaximumEligibilityLevel = new EligibilityLevelViewModel(leagueYear.Options.MaximumEligibilityLevel, false); DraftSystem = leagueYear.Options.DraftSystem.Value; PickupSystem = leagueYear.Options.PickupSystem.Value; ScoringSystem = leagueYear.Options.ScoringSystem.Name; UnlinkedGameExists = publishers.SelectMany(x => x.PublisherGames).Any(x => x.MasterGame.HasNoValue); Publishers = publishers.OrderBy(x => x.DraftPosition).Select(x => new PublisherViewModel(x, clock, nextDraftPublisher)).ToList(); Standings = publishers.OrderByDescending(x => x.TotalFantasyPoints).Select(x => new StandingViewModel(x, leagueYear.Options.ScoringSystem, leagueWideValues)).ToList(); if (!(userPublisher is null)) { UserPublisher = new PublisherViewModel(userPublisher, clock); } List <PlayerWithPublisherViewModel> playerVMs = new List <PlayerWithPublisherViewModel>(); bool allPublishersMade = true; foreach (var user in users) { var publisher = publishers.SingleOrDefault(x => x.User.UserID == user.UserID); if (publisher is null) { playerVMs.Add(new PlayerWithPublisherViewModel(leagueYear, user)); allPublishersMade = false; } else { playerVMs.Add(new PlayerWithPublisherViewModel(leagueYear, user, publisher, clock)); } } bool readyToSetDraftOrder = false; if (allPublishersMade) { Players = playerVMs.OrderBy(x => x.Publisher.DraftPosition).ToList(); readyToSetDraftOrder = true; } else { Players = playerVMs; } PlayStatus = new PlayStatusViewModel(playStatus, readyToSetDraftOrder, startDraftResult.Ready, startDraftResult.Errors, draftPhase); AvailableCounterPicks = availableCounterPicks.Select(x => new PublisherGameViewModel(x, clock)).ToList(); }
private IReadOnlyList <PickupBid> GetWinnableBids(IEnumerable <PickupBid> activeBidsForLeagueYear, LeagueOptions options, LeagueWideValues leagueWideValues) { List <PickupBid> winnableBids = new List <PickupBid>(); var enoughBudgetBids = activeBidsForLeagueYear.Where(x => x.BidAmount <= x.Publisher.Budget); var groupedByGame = enoughBudgetBids.GroupBy(x => x.MasterGame); foreach (var gameGroup in groupedByGame) { PickupBid bestBid; if (gameGroup.Count() == 1) { bestBid = gameGroup.First(); } else { var bestBids = gameGroup.MaxBy(x => x.BidAmount); var bestBidsByProjectedScore = bestBids.MinBy(x => x.Publisher.GetProjectedFantasyPoints(options.ScoringSystem, leagueWideValues)); bestBid = bestBidsByProjectedScore.First(); } winnableBids.Add(bestBid); } return(winnableBids); }