Esempio n. 1
0
        public void StandardElo()
        {
            var standardElo = new StandardElo();

            // Standard match
            var result = standardElo.Calculate(1600, 1500, 1500);

            Assert.That(result.WinnerDelta, Is.EqualTo(16));
            Assert.That(result.LoserDelta, Is.EqualTo(-16));

            // K32 vs K24
            result = standardElo.Calculate(1600, 1500, 2300);

            Assert.That(result.WinnerDelta, Is.EqualTo(32));
            Assert.That(result.LoserDelta, Is.EqualTo(-24));

            // K32 vs K16
            result = standardElo.Calculate(1600, 1600, 2402);

            Assert.That(result.WinnerDelta, Is.EqualTo(32));
            Assert.That(result.LoserDelta, Is.EqualTo(-16));

            // K24 vs K16
            result = standardElo.Calculate(1600, 2100, 2400);

            Assert.That(result.WinnerDelta, Is.EqualTo(20));
            Assert.That(result.LoserDelta, Is.EqualTo(-14));

            // K32 Tie
            result = standardElo.Calculate(1600, 1600, 1800, true);

            Assert.That(result.WinnerDelta, Is.EqualTo(8));
            Assert.That(result.LoserDelta, Is.EqualTo(-8));
        }
Esempio n. 2
0
        public void RejectMatch(int boardId, int matchId, string userName)
        {
            // Used to match against match Loser profile for verification of rejection authority.
            var userProfile = _repository.UserProfiles.FindProfile(userName);
            var board = _repository.GetBoardById(boardId);

            bool adminRejection = false;

            if (userProfile == null)
                throw new InvalidOperationException("Can not find your profile.");

            // All unresolved matches for this challenge board.
            var unresolvedMatches =
                _repository.GetUnresolvedMatchesByBoardId(boardId).OrderBy(x => x.VerificationDeadline).ToList();

            var rejectedMatch = unresolvedMatches.SingleOrDefault(x => x.MatchId == matchId);

            if (rejectedMatch == null)
                throw new ServiceException("Can not find match.");

            if(board.Owner.ProfileUserId == userProfile.UserId) // Board owner can reject anything
                adminRejection = true;
            else if (rejectedMatch.Loser.ProfileUserId != userProfile.UserId)  // Loser can reject match
                throw new ServiceException("You are not able to reject this match.");

            if(rejectedMatch.IsResolved)
                throw new ServiceException("This match has already been resolved.");

            if (DateTime.Now > rejectedMatch.VerificationDeadline)
                throw new ServiceException("The deadline for rejecting this match has passed.");

            rejectedMatch.Rejected = true;
            rejectedMatch.Resolved = DateTime.Now;
            rejectedMatch.Winner.RejectionsReceived++;
            rejectedMatch.Loser.RejectionsGiven++;

            // Anonymous list of unresolve matches taking place after the rejected match.
            // * These are the matches we need to recalculate
            var matchList =
                unresolvedMatches.Select(
                    x => new {x.MatchId, x.Created})
                                 .Where(x => x.Created >= rejectedMatch.Created && x.MatchId != rejectedMatch.MatchId);

            IScoringSystem system = new StandardElo();

            foreach (var match in matchList)
            {
                // Get unresolved matches prior to this one
                var filteredUnresolved =
                    unresolvedMatches.Where(x => x.Created <= match.Created && x.MatchId != match.MatchId).ToList();

                // Pick out the match to recalc and save
                var matchToRecalc = unresolvedMatches.First(x => x.MatchId == match.MatchId);

                // Figure unverified ratings.  Parses and sums unverified matches
                var unverifiedWinnerRank = matchToRecalc.Winner.CalculateUnverifiedRank(filteredUnresolved);
                var unverifiedLoserRank = matchToRecalc.Loser.CalculateUnverifiedRank(filteredUnresolved);

                // Run the recalc
                var eloRecalc = system.Calculate(board.StartingRating, unverifiedWinnerRank, unverifiedLoserRank,
                                                 matchToRecalc.Tied);

                // Update the ratings
                matchToRecalc.WinnerRatingDelta = eloRecalc.WinnerDelta.RoundToWhole();
                matchToRecalc.LoserRatingDelta = eloRecalc.LoserDelta.RoundToWhole();

                matchToRecalc.WinnerEstimatedRating = unverifiedWinnerRank + matchToRecalc.WinnerRatingDelta;
                matchToRecalc.LoserEstimatedRating = unverifiedLoserRank + matchToRecalc.LoserRatingDelta;
            }

            _repository.CommitChanges();

            _mailService.SendEmail(rejectedMatch.Winner.Profile.EmailAddress, rejectedMatch.Winner.Profile.UserName,
                                   "Match Rejected", EmailType.MatchRejectionNotice,
                                   new MatchRejectionNotice
                                   {
                                       RejectorName = adminRejection ? "the board administrator" : rejectedMatch.Loser.Name,
                                       RejectedName = rejectedMatch.Winner.Name,
                                       BoardName = board.Name,
                                       BoardOwnerName = board.Owner.Name
                                   });
        }
Esempio n. 3
0
        public Match GenerateMatch(int boardId, string winnerName, string loserName, bool tie = false)
        {
            var board = _repository.GetBoardByIdWithCompetitors(boardId);

            if(board == null)
                throw (new ServiceException("Can not find challenge board."));
            if (DateTime.Now >= board.End)
                throw (new ServiceException("This challenge board has ended."));

            var winner = board.Competitors.Active().FindCompetitorByName(winnerName);
            var loser = board.Competitors.Active().FindCompetitorByName(loserName);

            if(winner == null)
                throw (new ServiceException("You are not part of this challenge board."));
            if (loser == null)
                throw (new ServiceException("Can not find opponent."));
            if (loser.Name == winner.Name)
                throw (new ServiceException("You can't play yourself."));

            var match = new Match
            {
                Board = board,
                Tied = tie,
                Winner = winner,
                Loser = loser,
                Created = DateTime.Now,
                VerificationDeadline = DateTime.Now.AddHours(board.AutoVerification)
            };

            var unresolvedMatches = _repository.GetUnresolvedMatchesByBoardId(boardId, false).ToList();

            // Figure unverified ratings.  Parses and sums unverified matches
            var unverifiedWinnerRank = winner.CalculateUnverifiedRank(unresolvedMatches);
            var unverifiedLoserRank = loser.CalculateUnverifiedRank(unresolvedMatches);

            // Run scoring calculation
            IScoringSystem system = new StandardElo();
            var eloResult = system.Calculate(board.StartingRating, unverifiedWinnerRank, unverifiedLoserRank, tie);

            match.WinnerRatingDelta = eloResult.WinnerDelta.RoundToWhole();
            match.LoserRatingDelta = eloResult.LoserDelta.RoundToWhole();

            match.WinnerEstimatedRating = unverifiedWinnerRank + match.WinnerRatingDelta;
            match.LoserEstimatedRating = unverifiedLoserRank + match.LoserRatingDelta;

            return (match);
        }