예제 #1
0
        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);
        }
예제 #2
0
        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));
        }
예제 #3
0
        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);
        }
예제 #4
0
 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)));
 }
예제 #5
0
        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());
            }
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
        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));
        }
예제 #8
0
        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);
        }
예제 #10
0
        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));
 }
예제 #12
0
 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);
 }
예제 #13
0
 private void AddModifier(Models.Match.Match match, int minute, Guid cardId, float value)
 {
     match.Minutes[minute].Modifiers.Add(new Modifier(cardId, value, ModifierType.Fitness));
 }
예제 #14
0
 public void Drain(Models.Match.Match match, int minute)
 {
     DrainLineup(match, minute, match.HomeTeam.Squad.Lineup);
     DrainLineup(match, minute, match.AwayTeam.Squad.Lineup);
 }
예제 #15
0
 private void ApplyModifiers(Models.Match.Match match, int minute)
 {
     _fitnessDrainService.Drain(match, minute);
 }
예제 #16
0
        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)));
 }