Exemple #1
0
        public async Task No_matches_returns_MatchListingViewModel()
        {
            var filter            = new MatchFilter();
            var queryStringParser = new Mock <IMatchesRssQueryStringParser>();

            queryStringParser.Setup(x => x.ParseFilterFromQueryString(It.IsAny <NameValueCollection>())).Returns(filter);
            var matchFilterHumanizer = new Mock <IMatchFilterHumanizer>();

            var matchDataSource = new Mock <IMatchListingDataSource>();

            matchDataSource.Setup(x => x.ReadMatchListings(filter, MatchSortOrder.LatestUpdateFirst)).ReturnsAsync(new List <MatchListing>());

            using (var controller = new TestController(matchDataSource.Object, queryStringParser.Object, matchFilterHumanizer.Object, UmbracoHelper))
            {
                var result = await controller.Index(new ContentModel(Mock.Of <IPublishedContent>())).ConfigureAwait(false);

                Assert.IsType <MatchListingViewModel>(((ViewResult)result).Model);
            }
        }
        public async Task Page_title_is_set_to_humanized_filter()
        {
            var filter     = new MatchFilter();
            var dataSource = new Mock <IMatchListingDataSource>();
            var matchFilterQueryStringParser = new Mock <IMatchFilterQueryStringParser>();

            matchFilterQueryStringParser.Setup(x => x.ParseQueryString(It.IsAny <MatchFilter>(), It.IsAny <NameValueCollection>())).Returns(filter);
            var matchFilterHumanizer = new Mock <IMatchFilterHumanizer>();

            matchFilterHumanizer.Setup(x => x.MatchesAndTournaments(filter)).Returns("tournaments");
            matchFilterHumanizer.Setup(x => x.MatchingFilter(filter)).Returns(" matching filter");

            using (var controller = new TestController(dataSource.Object, matchFilterQueryStringParser.Object, matchFilterHumanizer.Object))
            {
                var result = await controller.Index(new ContentModel(Mock.Of <IPublishedContent>())).ConfigureAwait(false);

                Assert.Equal("tournaments matching filter", ((MatchListingViewModel)((ViewResult)result).Model).Metadata.PageTitle);
            }
        }
        private List <MatchResult> MatchEntitiesWithIndicesPreTokenizeApproach(ProcessedDataset processedDataset, List <string> dataset, string inputSentence, float threshold, int ngramSize = 3)
        {
            // get all input sentence possible tokens
            var sentenceTokens = StringTokenizer.GetAllPossibleTokens(inputSentence, processedDataset.MaximumWordCount, ngramSize);

            // calculate tokens TFIDF matrix
            var inputTokensTFIDFMatrix = TFIDFController.CalculateInputSenenteceTokensTFIDFMatrix(sentenceTokens, processedDataset, ngramSize);

            // calculate tokens cosine similarity
            var similarityValuesMatrix = DotProductCalculator.GetDotProduct(inputTokensTFIDFMatrix, processedDataset.TFIDFMatrix, matrix2Abs: processedDataset.TFIDFMatrixAbsoluteValues);

            // filter results
            var tfidfThreshold = 0.5f;
            var tfidfMatches   = MatchFilter.FilterByThresholdBatch(similarityValuesMatrix, dataset, sentenceTokens, tfidfThreshold);

            // post processing
            var updatedScoresMatches = PostprocessingController.UpdateMatchScores(tfidfMatches);

            return(MatchFilter.FilterByThreshold(updatedScoresMatches, threshold));
        }
Exemple #4
0
        public void DirectConfrontation1Match()
        {
            var matches = new Match[]
            {
                new Match {
                    IdHomeTeam = 1, IdVisitorTeam = 2, HomeScore = 30, VisitorScore = 1
                },
                new Match {
                    IdHomeTeam = 3, IdVisitorTeam = 2, HomeScore = 20, VisitorScore = 0
                },
                new Match {
                    IdHomeTeam = 1, IdVisitorTeam = 3, HomeScore = 1, VisitorScore = 47
                },
            };

            var table = new TeamDayResult[]
            {
                new TeamDayResult(2, 0, 0, 0, 0, 0, 0, 6)
                {
                    IdStage = 1, IdTeam = 1
                },
                new TeamDayResult(2, 0, 0, 0, 0, 0, 0, 6)
                {
                    IdStage = 1, IdTeam = 2
                },
                new TeamDayResult(2, 0, 0, 0, 0, 0, 0, 6)
                {
                    IdStage = 1, IdTeam = 3
                },
            };

            var matchFilter = new MatchFilter(matches);

            var classification = LeagueClassification.SortClassification(table, new int[] { 0, 3 }, matchFilter.GetMatchesForTeams);

            var c = classification.ToArray();

            Assert.AreEqual(3, c[0].IdTeam);
            Assert.AreEqual(1, c[1].IdTeam);
            Assert.AreEqual(2, c[2].IdTeam);
        }
Exemple #5
0
        public async Task Route_matching_club_returns_ClubViewModel()
        {
            var clubDataSource = new Mock <IClubDataSource>();

            clubDataSource.Setup(x => x.ReadClubByRoute(It.IsAny <string>())).ReturnsAsync(new Club());

            var filter = new MatchFilter();
            var matchFilterQueryStringParser = new Mock <IMatchFilterQueryStringParser>();

            matchFilterQueryStringParser.Setup(x => x.ParseQueryString(It.IsAny <MatchFilter>(), It.IsAny <NameValueCollection>())).Returns(filter);

            var matchesDataSource = new Mock <IMatchListingDataSource>();

            matchesDataSource.Setup(x => x.ReadMatchListings(filter, MatchSortOrder.MatchDateEarliestFirst)).ReturnsAsync(new List <MatchListing>());

            using (var controller = new TestController(clubDataSource.Object, matchesDataSource.Object, matchFilterQueryStringParser.Object, UmbracoHelper))
            {
                var result = await controller.Index(new ContentModel(Mock.Of <IPublishedContent>())).ConfigureAwait(false);

                Assert.IsType <ClubViewModel>(((ViewResult)result).Model);
            }
        }
Exemple #6
0
        public async Task Route_not_matching_location_returns_404()
        {
            var locationDataSource = new Mock <IMatchLocationDataSource>();

            locationDataSource.Setup(x => x.ReadMatchLocationByRoute(It.IsAny <string>(), false)).Returns(Task.FromResult <MatchLocation>(null));

            var filter = new MatchFilter();
            var matchFilterQueryStringParser = new Mock <IMatchFilterQueryStringParser>();

            matchFilterQueryStringParser.Setup(x => x.ParseQueryString(It.IsAny <MatchFilter>(), It.IsAny <NameValueCollection>())).Returns(filter);

            var matchesDataSource = new Mock <IMatchListingDataSource>();

            matchesDataSource.Setup(x => x.ReadMatchListings(filter, MatchSortOrder.MatchDateEarliestFirst)).ReturnsAsync(new List <MatchListing>());

            using (var controller = new TestController(locationDataSource.Object, matchesDataSource.Object, matchFilterQueryStringParser.Object, UmbracoHelper))
            {
                var result = await controller.Index(new ContentModel(Mock.Of <IPublishedContent>())).ConfigureAwait(false);

                Assert.IsType <HttpNotFoundResult>(result);
            }
        }
 public async Task <IEnumerable <ItemMatch> > GetMatches(DateTime date, MatchFilter filter)
 {
     return(await context.Matches
            .Where(m => m.KickoffDate.Date.Equals(date))
            .Where(m => string.IsNullOrEmpty(filter.Name) || m.Name.Contains(filter.Name))
            .Where(m => string.IsNullOrEmpty(filter.Events) || filter.Events.Contains(m.EventName))
            .OrderBy(m => m.KickoffDate)
            // .ThenBy(m => m.EventName)
            .Select(m => new ItemMatch()
     {
         Id = m.Id,
         EventName = m.EventName,
         KickoffDate = m.KickoffDate,
         Name = m.Name,
         Result = m.Result,
         Prediction = m.Predictions
                      .OrderByDescending(p => p.CreationDate)
                      .FirstOrDefault()
     })
            .Where(m => string.IsNullOrEmpty(filter.Gemstones) || filter.Gemstones.Contains(m.Prediction.Gemstone))
            .ToListAsync());
 }
        public async Task <HttpResponseMessage> GetAvailablePlayers(int?id = null, [FromUri] MatchFilter filter = null)
        {
            IEnumerable <TeamPlayer> list;

            // We remove the Id of the match filter because it s not intend to be in TODO ! Rename the filters property with a prefix OR remove ID
            if (filter != null)
            {
                filter.Id = null;
            }
            if (id == null)
            {
                //when no id specified, get all the available players for a home game
                list = await teamPlayerRepo.GetAllWithUnplayedMatches(Location.Home, filter);
            }
            else
            {
                // if we get an id argument, we need to retrieve the available players
                // that still have unplayed matched with player with Id = id
                list = await teamPlayerRepo.GetAvailableAwayOpponents(id.Value, filter);
            }

            return(Request.CreateResponse(HttpStatusCode.OK, list));
        }
        public IEnumerable <Match> GetMatches(MatchFilter filter)
        {
            if (filter == null)
            {
                filter = new MatchFilter();
            }

            if (filter.IsValid() == false)
            {
                throw new ArgumentException($"In filter instance {nameof(filter.From)} must be before {nameof(filter.To)}");
            }

            IEnumerable <Match> result = matchContext.Matches;

            if (filter.From.HasValue)
            {
                result = result.Where(x => x.KickoffAt >= filter.From.Value);
            }

            if (filter.To.HasValue)
            {
                result = result.Where(x => x.KickoffAt <= filter.To.Value);
            }

            if (filter.Group.HasValue)
            {
                result = result.Where(x => x.GroupName == filter.Group.Value);
            }

            if (string.IsNullOrEmpty(filter.Team) == false)
            {
                result = result.Where(x => x.HomeTeam.Equals(filter.Team, StringComparison.OrdinalIgnoreCase) ||
                                      x.AwayTeam.Equals(filter.Team, StringComparison.OrdinalIgnoreCase));
            }

            return(result);
        }
        public async Task <IEnumerable <DateGroup> > GetMatchesGroupedByDate(DateTime startDate, DateTime endDate, MatchFilter filter)
        {
            var matches = await context.Matches
                          .Where(m => m.KickoffDate.Date >= startDate)
                          .Where(m => m.KickoffDate.Date <= endDate)
                          .Where(m => string.IsNullOrEmpty(filter.Name) || m.Name.Contains(filter.Name))
                          .Where(m => string.IsNullOrEmpty(filter.Events) || filter.Events.Contains(m.EventName))
                          .OrderBy(m => m.KickoffDate)
                          // .ThenBy(m => m.EventName)
                          .Select(m => new ItemMatch()
            {
                Id          = m.Id,
                EventName   = m.EventName,
                KickoffDate = m.KickoffDate,
                Name        = m.Name,
                Result      = m.Result,
                Prediction  = m.Predictions
                              .OrderByDescending(p => p.CreationDate)
                              .FirstOrDefault()
            })
                          .Where(m => string.IsNullOrEmpty(filter.Gemstones) || filter.Gemstones.Contains(m.Prediction.Gemstone))
                          .ToListAsync();

            return(matches
                   .GroupBy(m => m.KickoffDate.Date)
                   .Select(g => new DateGroup()
            {
                Date = g.Key,
                Count = g.Count(),
                Matches = g.ToList()
            })
                   .ToList());
        }
        public async Task <IActionResult> GetMatchesSnapshot(DateTime date, TimeSpan snapshot, [FromQuery] MatchFilter filter)
        {
            var matches = await repository.GetMatchesSnapshot(date, snapshot, filter);

            return(Ok(matches));
        }
        /// <summary>
        /// Gets a list of matches and tournaments based on a query
        /// </summary>
        /// <returns>A list of <see cref="MatchListing"/> objects. An empty list if no matches or tournaments are found.</returns>
        public async virtual Task <List <MatchListing> > ReadMatchListings(MatchFilter filter, MatchSortOrder sortOrder)
        {
            if (filter is null)
            {
                filter = new MatchFilter();
            }

            if (!filter.IncludeMatches && !filter.IncludeTournaments)
            {
                return(new List <MatchListing>());
            }

            if (ExcludeTournamentsDueToMatchTypeFilter(filter.MatchResultTypes))
            {
                filter.IncludeTournaments = false;
            }

            using (var connection = _databaseConnectionFactory.CreateDatabaseConnection())
            {
                var selectSql  = new StringBuilder();
                var whereSql   = new StringBuilder();
                var parameters = new Dictionary <string, object>();
                var orderBy    = new List <string>();

                if (filter.IncludeMatches)
                {
                    // Join to MatchInnings only happens if there's a batting team, because otherwise all you get from it is extra rows to process with just a MatchInningsId
                    var matchSelectSql = $@"SELECT m.MatchId, m.MatchName, m.MatchRoute, m.StartTime, m.StartTimeIsKnown, m.MatchType, m.PlayerType, m.PlayersPerTeam, m.MatchResultType,
                                NULL AS TournamentQualificationType, NULL AS SpacesInTournament, m.OrderInTournament,
                                (SELECT TOP 1 AuditDate FROM {Tables.Audit} WHERE EntityUri = CONCAT('{Constants.EntityUriPrefixes.Match}', m.MatchId) ORDER BY AuditDate ASC) AS FirstAuditDate,
                                (SELECT TOP 1 AuditDate FROM {Tables.Audit} WHERE EntityUri = CONCAT('{Constants.EntityUriPrefixes.Match}', m.MatchId) ORDER BY AuditDate DESC) AS LastAuditDate,
                                mt.TeamRole, mt.MatchTeamId,
                                mt.TeamId,
                                i.MatchInningsId, i.Runs, i.Wickets,
                                ml.MatchLocationId, ml.SecondaryAddressableObjectName, ml.PrimaryAddressableObjectName, ml.Locality, ml.Town, ml.Latitude, ml.Longitude
                                FROM { Tables.Match } AS m
                                LEFT JOIN {Tables.MatchTeam} AS mt ON m.MatchId = mt.MatchId
                                LEFT JOIN {Tables.MatchInnings} AS i ON m.MatchId = i.MatchId AND i.BattingMatchTeamId = mt.MatchTeamId
                                LEFT JOIN {Tables.MatchLocation} AS ml ON m.MatchLocationId = ml.MatchLocationId ";

                    selectSql.Append(matchSelectSql);

                    var(matchWhereSql, matchParameters) = BuildMatchQuery(filter,
                                                                          $@"SELECT m.MatchId, m.OrderInTournament, m.StartTime
                           FROM {Tables.Match} AS m
                           <<JOIN>>
                           <<WHERE>> ");
                    whereSql.Append(matchWhereSql);

                    parameters = matchParameters;

                    if (filter.TournamentId != null)
                    {
                        orderBy.Add("OrderInTournament");
                    }
                }

                if (filter.IncludeMatches && filter.IncludeTournaments)
                {
                    selectSql.Append(" UNION ");
                    whereSql.Append(" UNION ");
                }

                if (filter.IncludeTournaments)
                {
                    var tournamentSelectSql = $@"SELECT tourney.TournamentId AS MatchId, tourney.TournamentName AS MatchName, tourney.TournamentRoute AS MatchRoute, tourney.StartTime, tourney.StartTimeIsKnown, 
                                NULL AS MatchType, tourney.PlayerType, tourney.PlayersPerTeam, NULL AS MatchResultType,
                                tourney.QualificationType AS TournamentQualificationType, tourney.SpacesInTournament, NULL AS OrderInTournament, 
                                (SELECT TOP 1 AuditDate FROM {Tables.Audit} WHERE EntityUri = CONCAT('{Constants.EntityUriPrefixes.Tournament}', tourney.TournamentId) ORDER BY AuditDate ASC) AS FirstAuditDate,
                                (SELECT TOP 1 AuditDate FROM {Tables.Audit} WHERE EntityUri = CONCAT('{Constants.EntityUriPrefixes.Tournament}', tourney.TournamentId) ORDER BY AuditDate DESC) AS LastAuditDate,
                                NULL AS TeamRole, NULL AS MatchTeamId,
                                NULL AS TeamId,
                                NULL AS MatchInningsId, NULL AS Runs, NULL AS Wickets,
                                ml.MatchLocationId, ml.SecondaryAddressableObjectName, ml.PrimaryAddressableObjectName, ml.Locality, ml.Town, ml.Latitude, ml.Longitude
                                FROM { Tables.Tournament} AS tourney
                                LEFT JOIN {Tables.MatchLocation} AS ml ON tourney.MatchLocationId = ml.MatchLocationId ";

                    selectSql.Append(tournamentSelectSql);

                    var(tournamentWhereSql, tournamentParameters) = BuildTournamentQuery(filter,
                                                                                         $@"SELECT tourney.TournamentId AS MatchId, NULL AS OrderInTournament, tourney.StartTime
                           FROM {Tables.Tournament} AS tourney
                           <<JOIN>>
                           <<WHERE>> ");

                    whereSql.Append(tournamentWhereSql);

                    foreach (var key in tournamentParameters.Keys)
                    {
                        if (!parameters.ContainsKey(key))
                        {
                            parameters.Add(key, tournamentParameters[key]);
                        }
                    }
                }

                if (sortOrder == MatchSortOrder.MatchDateEarliestFirst)
                {
                    orderBy.Add("StartTime");
                }
                else if (sortOrder == MatchSortOrder.LatestUpdateFirst)
                {
                    orderBy.Add("LastAuditDate DESC");
                }

                var pagedSql = $@"SELECT * FROM ({selectSql}) AS UnfilteredResults 
                                  WHERE MatchId IN 
                                  (
                                      SELECT MatchId FROM ({whereSql}) AS MatchingRecords 
                                      ORDER BY {string.Join(", ", orderBy.ToArray())}
                                      OFFSET @PageOffset ROWS FETCH NEXT @PageSize ROWS ONLY
                                  ) 
                                  ORDER BY {string.Join(", ", orderBy.ToArray())}";

                parameters.Add("@PageOffset", (filter.Paging.PageNumber - 1) * filter.Paging.PageSize);
                parameters.Add("@PageSize", filter.Paging.PageSize);

                var matches = await connection.QueryAsync <MatchListing, TeamInMatch, Team, MatchInnings, MatchLocation, MatchListing>(pagedSql,
                                                                                                                                       (matchListing, teamInMatch, team, matchInnings, location) =>
                {
                    if (teamInMatch != null)
                    {
                        teamInMatch.Team = team;
                        matchListing.Teams.Add(teamInMatch);

                        if (matchInnings != null)
                        {
                            matchInnings.BattingMatchTeamId = teamInMatch.MatchTeamId;
                            matchInnings.BattingTeam        = teamInMatch;
                        }
                        ;
                    }
                    if (matchInnings != null)
                    {
                        matchListing.MatchInnings.Add(matchInnings);
                    }
                    matchListing.MatchLocation = location;
                    return(matchListing);
                },
                                                                                                                                       new DynamicParameters(parameters),
                                                                                                                                       splitOn : "TeamRole, TeamId, MatchInningsId, MatchLocationId").ConfigureAwait(false);

                var listingsToReturn = matches.GroupBy(match => match.MatchRoute).Select(copiesOfMatch =>
                {
                    var matchToReturn          = copiesOfMatch.First();
                    matchToReturn.MatchInnings = copiesOfMatch.Select(match => match.MatchInnings.SingleOrDefault()).OfType <MatchInnings>().ToList();
                    matchToReturn.Teams        = copiesOfMatch.Select(match => match.Teams.SingleOrDefault()).OfType <TeamInMatch>().Distinct(new TeamInMatchEqualityComparer()).ToList();
                    return(matchToReturn);
                }).ToList();

                return(listingsToReturn);
            }
        }
        private static (string filteredSql, Dictionary <string, object> parameters) BuildTournamentQuery(MatchFilter filter, string sql)
        {
            if (filter is null)
            {
                throw new ArgumentNullException(nameof(filter));
            }

            var join = new List <string>();

            var where = new List <string>();
            var parameters = new Dictionary <string, object>();

            if (filter.PlayerTypes?.Count > 0)
            {
                where.Add("tourney.PlayerType IN @PlayerTypes");
                parameters.Add("@PlayerTypes", filter.PlayerTypes.Select(x => x.ToString()));
            }

            if (filter.TeamIds?.Count > 0)
            {
                join.Add($"INNER JOIN {Tables.TournamentTeam} tt ON tourney.TournamentId = tt.TournamentId");

                where.Add("tt.TeamId IN @TeamIds");
                parameters.Add("@TeamIds", filter.TeamIds);
            }

            if (filter.CompetitionIds?.Count > 0)
            {
                join.Add($"INNER JOIN {Tables.TournamentSeason} ts ON tourney.TournamentId = ts.TournamentId");
                join.Add($"INNER JOIN {Tables.Season} s ON ts.SeasonId = s.SeasonId");

                where.Add("s.CompetitionId IN @CompetitionIds");
                parameters.Add("@CompetitionIds", filter.CompetitionIds);
            }

            if (filter.SeasonIds?.Count > 0)
            {
                if (!string.Join(string.Empty, join).Contains(Tables.TournamentSeason))
                {
                    join.Add($"INNER JOIN {Tables.TournamentSeason} ts ON tourney.TournamentId = ts.TournamentId");
                }

                where.Add("ts.SeasonId IN @SeasonIds");
                parameters.Add("@SeasonIds", filter.SeasonIds);
            }

            if (filter.MatchLocationIds?.Count > 0)
            {
                where.Add("tourney.MatchLocationId IN @MatchLocationIds");
                parameters.Add("@MatchLocationIds", filter.MatchLocationIds);
            }

            if (filter.FromDate != null)
            {
                where.Add("tourney.StartTime >= @FromDate");
                parameters.Add("@FromDate", filter.FromDate.Value);
            }

            if (filter.UntilDate != null)
            {
                where.Add("tourney.StartTime <= @UntilDate");
                parameters.Add("@UntilDate", filter.UntilDate.Value);
            }

            if (filter.TournamentId != null)
            {
                where.Add("tourney.TournamentId = @TournamentId");
                parameters.Add("@TournamentId", filter.TournamentId.Value);
            }

            sql = sql.Replace("<<JOIN>>", join.Count > 0 ? string.Join(" ", join) : string.Empty)
                  .Replace("<<WHERE>>", where.Count > 0 ? "WHERE " + string.Join(" AND ", where) : string.Empty);

            return(sql, parameters);
        }
        public async Task <IActionResult> GetMatchesGroupedByDate(DateTime startDate, DateTime endDate, [FromQuery] MatchFilter filter)
        {
            var groups = await repository.GetMatchesGroupedByDate(startDate, endDate, filter);

            return(Ok(groups));
        }
        /// <summary>
        /// Tries to match the request and response offers, where we do the search in decreasing priority.
        /// </summary>
        /// <param name="material"></param>
        /// <param name="requestCount"></param>
        /// <param name="requestOffers"></param>
        /// <param name="responseCount"></param>
        /// <param name="responseOffers"></param>
        private static void MatchOffersClosest(
            TransferManager.TransferReason material,
            ushort[] requestCount, TransferManager.TransferOffer[] requestOffers,
            int requestPriorityMax, int requestPriorityMin,
            ushort[] responseCount, TransferManager.TransferOffer[] responseOffers,
            int responsePriorityMax, int responsePriorityMin,
            MatchFilter matchFilter)
        {
            int matchesMissed  = 0;
            int matchesOutside = 0;
            int matchesInside  = 0;

            TransferHistory.PurgeOldEvents(material);

            // We already previously patched the offers so that priority >= 1 correspond to local offers and priority == 0 correspond to outside offers.
            for (int requestPriority = requestPriorityMax; requestPriority >= requestPriorityMin; --requestPriority)
            {
                int requestCountIndex = (int)material * 8 + requestPriority;
                int requestSubCount   = requestCount[requestCountIndex];

                // Start searching at a random index!
                int requestSubIndex = m_randomizer.Int32(0, requestSubCount - 1);

                // Search request offers in decreasing priority only.  This is appropriate for services where the citizens are the ones calling for help.
                bool matched = false;
                for (int iter = 0; iter < requestSubCount; iter++)
                {
                    requestSubIndex++;
                    if (requestSubIndex >= requestSubCount)
                    {
                        requestSubIndex = 0;
                    }

                    var requestOffer    = requestOffers[requestCountIndex * 256 + requestSubIndex];
                    var requestPosition = requestOffer.Position;
                    int requestAmount   = requestOffer.Amount;

                    if (requestAmount == 0)
                    {
                        continue;
                    }

                    Logger.LogMaterial(
                        $"TransferManager::MatchOffersClosest: Searching for match for request={Utils.ToString(ref requestOffer, material)}",
                        material);

                    m_currentBuildingExclusions.Clear();

                    for (int iter2 = 0; iter2 < 10 && requestAmount != 0; iter2++)
                    {
                        int   bestResponsePriority = -1;
                        int   bestResponseSubIndex = -1;
                        float bestDistanceSquared  = float.MaxValue;

                        for (int responsePriority = responsePriorityMax; responsePriority >= responsePriorityMin; --responsePriority)
                        {
                            // Do not match to outside offer if we can match locally.
                            if (bestResponsePriority != -1 && responsePriority == 0)
                            {
                                break;
                            }

                            int responseCountIndex = (int)material * 8 + responsePriority;
                            int responseSubCount   = responseCount[responseCountIndex];

                            for (int responseSubIndex = 0; responseSubIndex < responseSubCount; ++responseSubIndex)
                            {
                                var responseOffer = responseOffers[responseCountIndex * 256 + responseSubIndex];

                                if (requestPriority == 0 || responsePriority == 0)
                                {
                                    if (TransferHistory.IsRestricted(material, requestOffer.Building, responseOffer.Building))
                                    {
                                        continue;
                                    }
                                }

                                // Not sure how this could happen, but ...
                                if (responseOffer.Amount == 0)
                                {
                                    continue;
                                }

                                if (responseOffer.Building != 0 && m_currentBuildingExclusions.Contains(responseOffer.Building))
                                {
                                    continue;
                                }

                                if (IsSameLocation(ref requestOffer, ref responseOffer))
                                {
                                    continue;
                                }

                                if (!matchFilter(
                                        material,
                                        ref requestOffer, requestPriority,
                                        ref responseOffer, responsePriority))
                                {
                                    continue;
                                }

                                // A rather hacky way to take into account routing errors between two buildings.  The
                                // m_buildingToBuildingExclusions list contains a list of ints (upper 16 bits contains
                                // source building id and the lower 16 bits contains the target building id) that
                                // indicate that a pathfinding error occurred between the source and target buildings.
                                // If so, go ahead and exclude the possibility of a match between these buildings for
                                // this current MatchOffers call, but allow for such a possibility in the next round.
                                if (requestOffer.Building != 0 && responseOffer.Building != 0)
                                {
                                    if (ContainsBuildingToBuildingExclusion(requestOffer.Building, responseOffer.Building))
                                    {
                                        Logger.Log($"TransferManagerMod::MatchOffersClosest: Detected path find failure between {requestOffer.Building} and {responseOffer.Building}, excluding match!");
                                        // Give it a chance to remove the exclusion, in case the user or game fixed the path finding problem.
                                        if (m_randomizer.Int32(10) < 2)
                                        {
                                            RemoveBuildingToBuildingExclusion(requestOffer.Building, responseOffer.Building);
                                        }

                                        continue;
                                    }

                                    if (ContainsBuildingToBuildingExclusion(responseOffer.Building, requestOffer.Building))
                                    {
                                        Logger.Log($"TransferManagerMod::MatchOffersClosest: Detected path find failure between {requestOffer.Building} and {responseOffer.Building}, excluding match!");
                                        // Give it a chance to remove the exclusion, in case the user or game fixed the path finding problem.
                                        if (m_randomizer.Int32(10) < 2)
                                        {
                                            RemoveBuildingToBuildingExclusion(responseOffer.Building, requestOffer.Building);
                                        }

                                        continue;
                                    }
                                }

                                var distanceSquared  = Vector3.SqrMagnitude(responseOffer.Position - requestPosition);
                                var foundBetterMatch = false;

                                if (bestResponsePriority == -1)
                                {
                                    foundBetterMatch = true;
                                }

                                if (responsePriority == bestResponsePriority)
                                {
                                    if (distanceSquared < bestDistanceSquared)
                                    {
                                        foundBetterMatch = true;
                                    }
                                    else if (distanceSquared < 1.25 * bestDistanceSquared && m_randomizer.Int32(10) < 2)
                                    {
                                        // Give the algorithm a chance not to get stuck in a "local minimum" ...
                                        foundBetterMatch = true;
                                    }
                                    else if ((requestPriority == 0 || responsePriority == 0) && m_randomizer.Int32(10) < 5)
                                    {
                                        foundBetterMatch = true;
                                    }
                                }

                                // Magic number 0.75.  Allow matching a lower priority offer only if it is substantially closer.
                                if (responsePriority < bestResponsePriority && distanceSquared < 0.75 * bestDistanceSquared)
                                {
                                    foundBetterMatch = true;
                                }

                                if (foundBetterMatch)
                                {
                                    bestResponsePriority = responsePriority;
                                    bestResponseSubIndex = responseSubIndex;
                                    bestDistanceSquared  = distanceSquared;
                                }
                            }
                        }

                        if (bestResponsePriority != -1)
                        {
                            int responseCountIndex = (int)material * 8 + bestResponsePriority;
                            var responseOffer      = responseOffers[responseCountIndex * 256 + bestResponseSubIndex];
                            int responseAmount     = responseOffer.Amount;

                            Logger.LogMaterial(
                                $"TransferManager::MatchOffersClosest: Matched {Utils.ToString(ref requestOffer, material)} to {Utils.ToString(ref responseOffer, material)}!",
                                material);

                            int delta = Mathf.Min(requestAmount, responseAmount);
                            if (delta != 0)
                            {
                                var success = StartTransfer(material, requestOffer, responseOffer, delta);
                                if (!success)
                                {
                                    Logger.LogWarning($"TransferManager::MatchOffersClosest: Matched {Utils.ToString(ref requestOffer, material)} to {Utils.ToString(ref responseOffer, material)}, but was unable to start the transfer!!");
                                    m_currentBuildingExclusions.Add(responseOffer.Building);
                                    continue;
                                }

                                matched = true;
                                if (requestPriority == 0 || bestResponsePriority == 0)
                                {
                                    // Only record matches to outside connections for now ...
                                    TransferHistory.RecordMatch(material, requestOffer.Building, responseOffer.Building);
                                    matchesOutside++;
                                }
                                else
                                {
                                    matchesInside++;
                                }
                            }

                            requestAmount  -= delta;
                            responseAmount -= delta;
                            if (responseAmount == 0)
                            {
                                int responseSubCount = responseCount[responseCountIndex] - 1;
                                responseCount[responseCountIndex] = (ushort)responseSubCount;
                                responseOffers[responseCountIndex * 256 + bestResponseSubIndex] = responseOffers[responseCountIndex * 256 + responseSubCount];
                            }
                            else
                            {
                                responseOffer.Amount = responseAmount;
                                responseOffers[responseCountIndex * 256 + bestResponseSubIndex].Amount = responseAmount;
                            }

                            requestOffer.Amount = requestAmount;
                            requestOffers[requestCountIndex * 256 + requestSubIndex].Amount = requestAmount;
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (requestPriority > 0 && !matched)
                    {
                        Logger.LogMaterial(
                            $"TransferManager::MatchOffersClosest: Failed to match {Utils.ToString(ref requestOffer, material)}",
                            material);
                        matchesMissed++;
                    }
                }

                if (requestSubCount > 0)
                {
                    Logger.LogMaterial(
                        $"TransferManager::MatchOffersClosest: material={material}, request_priority={requestPriority}, outside_matches={matchesOutside}, inside_matches={matchesInside}, missed_matches={matchesMissed}",
                        material);
                }
            }
        }
        public async Task <IActionResult> GetMatches(DateTime date, [FromQuery] MatchFilter filter)
        {
            var matches = await repository.GetMatches(date, filter);

            return(Ok(matches));
        }
Exemple #17
0
 // GET: Matches
 public ActionResult Matches(MatchFilter filter)
 {
     return(View(filter));
 }
 public string Serialize(MatchFilter filter)
 {
     return(Serialize(filter, null));
 }
Exemple #19
0
        public async Task <Match> GetMatchesAsync(MatchFilter matchType)
        {
            var result = await GetRequestAsyncV1 <Match>($"/matches/{Name}/{Tag}?filter=" + matchType.ToString().ToLower());

            return(result);
        }
        public async Task <IActionResult> GetBettingHistory(DateTime startDate, DateTime endDate, [FromQuery] MatchFilter filter)
        {
            var groups = await repository.GetMatchesGroupedByDate(startDate, endDate, filter);

            var bettingHistory = new BettingHistoryBuilder(groups).BuildBettingHistory();

            return(Ok(bettingHistory));
        }
 /// <inheritdoc />
 public async Task <int> ReadTotalMatches(MatchFilter filter)
 {
     return(await _matchListingDataSource.ReadTotalMatches(filter).ConfigureAwait(false));
 }
        private static (string filteredSql, Dictionary <string, object> parameters) BuildMatchQuery(MatchFilter filter, string sql)
        {
            if (filter is null)
            {
                throw new ArgumentNullException(nameof(filter));
            }

            var join = new List <string>();

            var where = new List <string>();
            var parameters = new Dictionary <string, object>();

            if (filter.MatchTypes?.Count > 0)
            {
                where.Add("m.MatchType IN @MatchTypes");
                parameters.Add("@MatchTypes", filter.MatchTypes.Select(x => x.ToString()));
            }

            if (filter.PlayerTypes?.Count > 0)
            {
                where.Add("m.PlayerType IN @PlayerTypes");
                parameters.Add("@PlayerTypes", filter.PlayerTypes.Select(x => x.ToString()));
            }

            if (filter.MatchResultTypes?.Count > 0)
            {
                if (filter.MatchResultTypes.Contains(null) && filter.MatchResultTypes.Count == 1)
                {
                    where.Add("m.MatchResultType IS NULL");
                }
                else if (filter.MatchResultTypes.Contains(null) && filter.MatchResultTypes.Count > 1)
                {
                    where.Add("(m.MatchResultType IS NULL OR m.MatchResultType IN @MatchResultTypes)");
                    parameters.Add("@MatchResultTypes", filter.MatchResultTypes.Where(x => x.HasValue).Select(x => x.ToString()));
                }
                else
                {
                    where.Add("m.MatchResultType IN @MatchResultTypes");
                    parameters.Add("@MatchResultTypes", filter.MatchResultTypes.Select(x => x.ToString()));
                }
            }

            if (filter.TeamIds?.Count > 0)
            {
                if (!sql.Contains(Tables.MatchTeam))
                {
                    join.Add($"INNER JOIN {Tables.MatchTeam} mt ON m.MatchId = mt.MatchId");
                }

                where.Add("mt.TeamId IN @TeamIds");
                parameters.Add("@TeamIds", filter.TeamIds);
            }

            if (filter.CompetitionIds?.Count > 0)
            {
                join.Add($"INNER JOIN {Tables.Season} s ON m.SeasonId = s.SeasonId");

                where.Add("s.CompetitionId IN @CompetitionIds");
                parameters.Add("@CompetitionIds", filter.CompetitionIds);
            }

            if (filter.SeasonIds?.Count > 0)
            {
                where.Add("m.SeasonId IN @SeasonIds");
                parameters.Add("@SeasonIds", filter.SeasonIds);
            }

            if (filter.MatchLocationIds?.Count > 0)
            {
                where.Add("m.MatchLocationId IN @MatchLocationIds");
                parameters.Add("@MatchLocationIds", filter.MatchLocationIds);
            }

            if (filter.FromDate != null)
            {
                where.Add("m.StartTime >= @FromDate");
                parameters.Add("@FromDate", filter.FromDate.Value);
            }

            if (filter.UntilDate != null)
            {
                where.Add("m.StartTime <= @UntilDate");
                parameters.Add("@UntilDate", filter.UntilDate.Value);
            }

            if (filter.IncludeTournamentMatches == false)
            {
                where.Add("m.TournamentId IS NULL");
            }

            if (filter.TournamentId != null)
            {
                where.Add("m.TournamentId = @TournamentId");
                parameters.Add("@TournamentId", filter.TournamentId.Value);
            }

            sql = sql.Replace("<<JOIN>>", join.Count > 0 ? string.Join(" ", join) : string.Empty)
                  .Replace("<<WHERE>>", where.Count > 0 ? "WHERE " + string.Join(" AND ", where) : string.Empty);

            return(sql, parameters);
        }
Exemple #23
0
        public void MatchFilterReturnsFirstSubstringMatchedByExpression()
        {
            var filter = new MatchFilter(new Regex("[a-z]+"));

            Assert.Equal("oo", filter.Apply("Foo"));
        }