public async Task KickOff(Guid sessionId) { var session = _matchmakingService.GetSession(sessionId); var match = new Models.Match.Match { Id = sessionId, HomeTeam = new TeamDetails { UserId = session.HostPlayerId } }; match.HomeTeam.Squad = BuildSquad(await _bus.RequestAsync <GetSquadRequest, GetSquadResponse>(new GetSquadRequest(match.HomeTeam.UserId))); match.AwayTeam = new TeamDetails { UserId = session.JoinedPlayerId.Value }; match.AwayTeam.Squad = BuildSquad(await _bus.RequestAsync <GetSquadRequest, GetSquadResponse>(new GetSquadRequest(match.AwayTeam.UserId))); match.KickOff = DateTime.Now; var simulatedMatch = _matchEngine.Simulate(match); await _matchRepository.CreateAsync(simulatedMatch); }
public IEvent SpawnEvent(Card card, Guid squadId, Models.Match.Match match) { var oppositionsDefenceRating = _ratingService.CurrentRating(PositionalArea.DEF, match, match.GetOppositionSquad(squadId)); var shootersRating = _ratingService.CurrentRating(card.Id, match, match.GetSquad(squadId)); var shotOnTargetChance = (int)Math.Round(oppositionsDefenceRating + shootersRating * Constants.ShooterAgainstDefendersModifier); var randomNumber = _randomnessProvider.Next(0, shotOnTargetChance); if (randomNumber <= shootersRating * Constants.ShooterAgainstDefendersModifier) { var gkRating = _ratingService.CurrentRating(PositionalArea.GK, match, match.GetOppositionSquad(squadId)); var goalChanceAccum = (int)Math.Round(gkRating + shootersRating * Constants.ShooterAgainstGkModifier); var goalRandomNumber = _randomnessProvider.Next(0, goalChanceAccum); if (goalRandomNumber <= shootersRating * Constants.ShooterAgainstGkModifier) { return(new Goal(card.Id, squadId)); } return(new ShotOnTarget(card.Id, squadId)); } return(new ShotOffTarget(card.Id, squadId)); }
private void SimulateMinute(Models.Match.Match match, int minute) { var inPossession = _possessionService.InPossession(match, out var notInPossession, out var homePossChance, out var awayPossChance); var action = _actionService.RollAction(); if (action != null) { var affectedSquad = action.AffectsTeamInPossession ? inPossession : notInPossession; var affectedCard = _actionService.RollCard(affectedSquad, action, match.Minutes); if (affectedCard != null) { var @event = action.SpawnEvent(affectedCard, affectedSquad.Id, match); if (@event != null) { match.Minutes[minute].Events.Add(@event); } } } ApplyModifiers(match, minute); AssignStats(match, minute, inPossession, homePossChance, awayPossChance); }
public int PossessionChance(Squad squad, Models.Match.Match match) { return((int)Math.Round((_ratingService.CurrentRating(PositionalArea.GK, match, squad) * 0.1) + (_ratingService.CurrentRating(PositionalArea.DEF, match, squad) * 0.5) + (_ratingService.CurrentRating(PositionalArea.MID, match, squad) * 1) + (_ratingService.CurrentRating(PositionalArea.ATT, match, squad) * 0.5))); }
private void DrainLineup(Models.Match.Match match, int minute, IDictionary <string, IEnumerable <Card> > lineup) { var allCards = lineup.SelectMany(x => x.Value); foreach (var card in allCards) { AddModifier(match, minute, card.Id, CalculateFitnessDrain()); } }
/// <summary> /// Reentrant method for simulating a match /// </summary> /// <param name="match"></param> /// <returns></returns> public Models.Match.Match Simulate(Models.Match.Match match) { match.AsAtElapsed(true); for (var minute = match.Elapsed; minute < Constants.MatchLengthInMinutes; minute++) { SimulateMinute(match, minute); } return(match); }
public int CurrentRating(PositionalArea positionalArea, Models.Match.Match match, Squad squad) { var players = squad.Lineup.Where(x => x.Value != null && x.Key == positionalArea.ToString()).SelectMany(x => x.Value).ToList(); var sentOffCardIds = match.Minutes.SelectMany(x => x.Events).Where(x => x is RedCard).Select(x => x.CardId); var onTheField = players.Where(x => x != null && !sentOffCardIds.Contains(x.Id)).ToList(); if (onTheField.Count == 0 || players.Count == 0) { return(0); } return((int)Math.Round((onTheField.Sum(x => x.Rating * 0.7) + onTheField.Sum(x => _calculatedCardStatService.Fitness(match, x.Id) * 0.3)) / players.Count)); }
public Squad InPossession(Models.Match.Match match, out Squad notInPossession, out int homeChance, out int awayChance) { homeChance = PossessionChance(match.HomeTeam.Squad, match); awayChance = PossessionChance(match.AwayTeam.Squad, match); var homePossession = ChanceHelper.CumulativeTrueOrFalse(homeChance, awayChance); if (homePossession) { notInPossession = match.AwayTeam.Squad; return(match.HomeTeam.Squad); } else { notInPossession = match.HomeTeam.Squad; return(match.AwayTeam.Squad); } }
private async Task <Models.Match.Match> ConvertRiotMatchReferenceToDbMatch(MatchReference riotMatchReference) { try { var newDbMatch = new Models.Match.Match(); var riotMatch = await _throttledRequestHelper.SendThrottledRequest(async() => await _riotApi.Match.GetMatchAsync(Region.euw, riotMatchReference.GameId)); if (riotMatch != null && riotMatch.QueueId == LeagueQueue.RankedSoloId) { newDbMatch.GameId = riotMatch.GameId; newDbMatch.GameDuration = riotMatch.GameDuration; newDbMatch.GameDate = riotMatch.GameCreation; newDbMatch.GamePatch = riotMatch.GameVersion; newDbMatch.WinningTeamId = riotMatch.Participants.FirstOrDefault(x => x.Stats.Win)?.TeamId; var winningTeamParticipants = riotMatch.Participants.Where(x => x.TeamId == newDbMatch.WinningTeamId); var winningTeamParticipantIdentifies = riotMatch.ParticipantIdentities.Where(x => winningTeamParticipants.Any(y => y.ParticipantId == x.ParticipantId)); var winningTeamstats = riotMatch.Teams.FirstOrDefault(x => x.TeamId == newDbMatch.WinningTeamId); newDbMatch.Teams.Add(ConvertRiotParticipantsToDbTeam(winningTeamParticipantIdentifies, winningTeamParticipants, winningTeamstats)); var losingTeamParticipants = riotMatch.Participants.Where(x => x.TeamId != newDbMatch.WinningTeamId); var losingTeamParticipantIdentifies = riotMatch.ParticipantIdentities.Where(x => losingTeamParticipants.Any(y => y.ParticipantId == x.ParticipantId)); var losingTeamStats = riotMatch.Teams.FirstOrDefault(x => x.TeamId != newDbMatch.WinningTeamId); newDbMatch.Teams.Add(ConvertRiotParticipantsToDbTeam(losingTeamParticipantIdentifies, losingTeamParticipants, losingTeamStats)); return(newDbMatch); } } catch (Exception) { } return(null); }
public IEvent SpawnEvent(Card card, Guid squadId, Models.Match.Match match) { int randomNumber = _randomnessProvider.Next(1, 40); if (randomNumber == 1) { return(new RedCard(card.Id, squadId)); } if (randomNumber >= 2 && randomNumber < 5) { var yellowCards = match.Minutes.SelectMany(x => x.Events).Where(x => x is YellowCard).Select(x => x.CardId); if (yellowCards.Contains(card.Id)) { return(new RedCard(card.Id, squadId)); //TODO return yellow and red event } return(new YellowCard(card.Id, squadId)); } if (randomNumber >= 5) { return(new Events.Foul(card.Id, squadId)); } return(null); }
private static IEnumerable <Modifier> EffectiveModifiers(Models.Match.Match match, Guid cardId, ModifierType type) { return(match.Minutes.SelectMany(x => x.Modifiers).Where(x => x.CardId == cardId && x.Type == type)); }
private static void AssignStats(Models.Match.Match match, int minute, Squad inPossession, int homePossChance, int awayPossChance) { match.Minutes[minute].Stats = new MinuteStats(inPossession.Id, homePossChance, awayPossChance); }
private void AddModifier(Models.Match.Match match, int minute, Guid cardId, float value) { match.Minutes[minute].Modifiers.Add(new Modifier(cardId, value, ModifierType.Fitness)); }
public void Drain(Models.Match.Match match, int minute) { DrainLineup(match, minute, match.HomeTeam.Squad.Lineup); DrainLineup(match, minute, match.AwayTeam.Squad.Lineup); }
private void ApplyModifiers(Models.Match.Match match, int minute) { _fitnessDrainService.Drain(match, minute); }
public int CurrentRating(Guid cardId, Models.Match.Match match, Squad squad) { var card = squad.Lineup.SelectMany(x => x.Value).FirstOrDefault(x => x.Id == cardId); return((int)Math.Round(card.Rating * 0.33 + _calculatedCardStatService.Fitness(match, card.Id) * 0.33 + card.Chemistry * 0.33)); }
public int Fitness(Models.Match.Match match, Guid cardId) { return((int)Math.Round(FitnessUpperBound - EffectiveModifiers(match, cardId, ModifierType.Fitness).Sum(x => x.DrainValue))); }