Beispiel #1
0
        /// <inheritdoc/>
        public IMatchmakerQueueTask <T> EnqueueGroup(EntityGroup <T> entities, EventHandler <MatchmakingStateChangedEventArgs <T> > callback = null)
        {
            RankingMatchmakerQueueTask <T> task = new RankingMatchmakerQueueTask <T>(this, entities, callback);
            QueueGroup queueGroup = new QueueGroup {
                task = task
            };

            MatchRankingContext <T> context = new MatchRankingContext <T>(DiscardThreshold);

            //Look at all other entities in queue and rate them
            lock (queueSnapshot)
                AddMatchesToQueueGroup(queueGroup, queueSnapshot, context);

            lock (inQueue)
            {
                //Rate those to be added in future
                AddMatchesToQueueGroup(queueGroup, inQueue, context);

                //Add to in queue for next tick/flush
                inQueue.Enqueue(queueGroup);
            }

            return(task);
        }
Beispiel #2
0
        /// <summary>
        ///     Calculates and adds matches to the given group.
        /// </summary>
        /// <param name="group">The group to calculate for.</param>
        /// <param name="groups">The groups to calculate against.</param>
        /// <param name="context">The context for the matchmaker.</param>
        private void AddMatchesToQueueGroup(QueueGroup group, IEnumerable <QueueGroup> groups, MatchRankingContext <T> context)
        {
            foreach (QueueGroup other in groups)
            {
                float outerAcc = 0;
                bool  failed   = false;
                foreach (T entity in group.task.Entities)
                {
                    float acc = 0;
                    foreach (T otherEntity in other.task.Entities)
                    {
                        float value = GetSuitabilityMetric(entity, otherEntity, context);

                        //Check individual discard threshold, if not enough ignore the group
                        if (value < DiscardThreshold)
                        {
                            failed = true;
                            break;
                        }

                        acc += value;
                    }

                    //If we've already failed then just skip the reset
                    if (failed)
                    {
                        break;
                    }

                    outerAcc += acc / other.task.Entities.Count;
                }

                //Already failed, don't add match
                if (failed)
                {
                    continue;
                }

                outerAcc /= group.task.Entities.Count;

                //If a good enough match then add to our list of posible matches
                if (outerAcc >= GroupDiscardThreshold)
                {
                    group.matches.AddLast(new Match {
                        other = other, value = outerAcc
                    });
                }
            }
        }
Beispiel #3
0
 /// <summary>
 ///     Returns a suitability metric for the given entity pair.
 /// </summary>
 /// <param name="entity1">The first entity.</param>
 /// <param name="entity2">The second entity.</param>
 /// <param name="context">Additional information about the ranking.</param>
 /// <returns>A value between 0 and 1 indicating the suitability where 1 is the perfect match for each other and 0 is the worst possible match.</returns>
 public abstract float GetSuitabilityMetric(T entity1, T entity2, MatchRankingContext <T> context);