예제 #1
0
        public async Task<Match> Update(Match match, string userMatricule)
        {
            //récupération du match existant
            Match currentMatch = await Get(match.Id);
            if (currentMatch == null)
            {
                throw new NullReferenceException(string.Format("le match avec l'id {0} est introuvable", match.Id));
            }

            if (currentMatch.CreatorId != userMatricule)
                throw new InvalidOperationException("Seul le créateur du match peut le modifier");

            //suppression des équipes
            currentMatch.Teams.ToList().ForEach(t => _teamStore.SetState(t, EntityState.Deleted));
            currentMatch.Teams.Clear();


            //recréation des équipes
            List<string> matricules = match.Teams.SelectMany(p => p.Players).Where(p => p != null).Select(p => p.Matricule).ToList();
            var players = await _playerStore.GetFromMatricules(matricules);

            foreach (Team team in match.Teams.Where(team => team != null && team.Players != null))
            {
                team.Id = 0;
                team.Players = team.Players.Where(p => p != null).Select(m => players.FirstOrDefault(j => m.Matricule == j.Matricule)).Where(p => p != null).ToList();
                currentMatch.Teams.Add(team);
            }
            await _teamStore.Add(match.Teams);

            //maj du match
            currentMatch.Date = match.Date;
            currentMatch.Name = match.Name;
            currentMatch.Points = match.Points;
            currentMatch.Private = match.Private;
            currentMatch.Ranked = match.Ranked;
            currentMatch.Sleeves = match.Sleeves;
            currentMatch.SportKey = match.SportKey;

            await _matchStore.SaveChangesAsync();

            return match;
        }
예제 #2
0
        public async Task<Match> Start(Match match, string userMatricule)
        {
            //récupération du match existant
            Match currentMatch = await Get(match.Id);
            if (currentMatch == null)
            {
                throw new NullReferenceException(string.Format("le match avec l'id {0} est introuvable", match.Id));
            }


            if (currentMatch.State != StateEnum.Opened)
                throw new InvalidOperationException("Le match est déjà en cours ou clos");

            if (currentMatch.CreatorId != userMatricule)
                throw new InvalidOperationException("Seul le créateur du match peut le démarrer");
            
            if(currentMatch.Randomize)
            RandomizeTeams(match);

            currentMatch.State = StateEnum.InProgress;

            await _matchStore.SaveChangesAsync();

            return currentMatch;
        }
예제 #3
0
        public async Task<Match> Leave(Match match, string playerMatricule, string userMatricule)
        {
            var currentMatch = await _matchStore.Get(match.Id);

            if (currentMatch == null)
                throw new InstanceNotFoundException("Le match est introuvable");

            if (currentMatch.State == StateEnum.Draw || currentMatch.State == StateEnum.Won)
                throw new InvalidOperationException("Le match est déjà clos");

            if (playerMatricule != userMatricule && currentMatch.CreatorId != userMatricule)
                throw new InvalidOperationException("Seul le créateur du match peut modifier sa composition");

            var player = await _playerStore.GetFromMatricule(playerMatricule);
            if (player == null)
                throw new InvalidOperationException("Le joueur est introuvable");

            var team = currentMatch.Teams.SingleOrDefault(t => t.Players.Select(p => p.Matricule.ToLowerInvariant()).Contains(playerMatricule.ToLowerInvariant()));
            if (team == null)
                throw new InvalidOperationException("Le joueur ne fait parti d'aucune équipe");


            team.Players.Remove(player);
            await _playerStore.SaveChangesAsync();


            return await Task.FromResult(currentMatch);
        }
예제 #4
0
        private void RandomizeTeams(Match match, bool removeEmptyTeams = true)
        {
            //récupération des joueurs
            var rnd = new Random();
            List<Player> players = match.Teams.SelectMany(p => p.Players).Where(p => p != null).OrderBy(item => rnd.Next()).ToList();

            match.Teams.ForEach(t => t.Players.Clear());
            while (players.Count > 0)
            {
                foreach (var team in match.Teams)
                {
                    if (players.Count <= 0)
                        break;
                    var player = players.First();
                    players.RemoveAt(0);
                    team.Players.Add(player);
                }
            }

            if (!removeEmptyTeams)
                return;

            //suppression des équipes vides
            match.Teams.Where(t => t.Players.Count == 0).ToList().ForEach(t => _teamStore.SetState(t, EntityState.Deleted));

            match.Teams = match.Teams.Where(t => t.Players.Count > 0).ToList();
        }
예제 #5
0
        public async Task<Match> Join(Match match, int teamId, string playerMatricule, string userMatricule)
        {
            var currentMatch = await _matchStore.Get(match.Id);

            if (currentMatch == null)
                throw new InstanceNotFoundException("Le match est introuvable");


            if (currentMatch.State == StateEnum.Draw || currentMatch.State == StateEnum.Won)
                throw new InvalidOperationException("Le match est déjà clos");

            if (playerMatricule != userMatricule && currentMatch.CreatorId != userMatricule)
                throw new InvalidOperationException("Seul le créateur du match peut modifier sa composition");

            var player = await _playerStore.GetFromMatricule(playerMatricule);
            if (player == null)
                throw new InvalidOperationException("Le joueur est introuvable");

            if (currentMatch.Teams.SelectMany(t => t.Players).Select(p => p.Matricule.ToLowerInvariant()).Contains(playerMatricule.ToLowerInvariant()))
                throw new InvalidOperationException("Le joueur fait déjà parti d'une équipe");

            var team = currentMatch.Teams.SingleOrDefault(t => t.Id == teamId);
            if (team == null)
                throw new InvalidOperationException("L'équipe n'est pas liée au match");

            var currentSport = await _sportStore.Get(currentMatch.SportKey);
            if (team.Players.Count >= currentSport.MaxPlayers)
                throw new InvalidOperationException("L'équipe est déjà complète");

            team.Players.Add(player);
            await _playerStore.SaveChangesAsync();

            return await Task.FromResult(currentMatch);
        }
예제 #6
0
        public async Task<Match> Add(Match match, string userMatricule)
        {
            match.CreatorId = userMatricule;
            foreach (Team team in match.Teams.Where(team => team != null && team.Players != null))
            {
                List<string> players = team.Players.Where(p => p != null).Select(p => p.Matricule).ToList();
                team.Players = await _playerStore.GetFromMatricules(players);
            }
            await _teamStore.Add(match.Teams);
            await _matchStore.Add(match);
            await _matchStore.SaveChangesAsync();

            return match;
        }
예제 #7
0
        public async Task<Match> Close(Match match, string userMatricule)
        {
            var currentMatch = await _matchStore.GetWithPlayersAndRanks(match.Id);

            if (currentMatch.State == StateEnum.Draw || currentMatch.State == StateEnum.Won)
                throw new InvalidOperationException("Le match est déjà clos");

            if (string.IsNullOrWhiteSpace(match.Scores))
                throw new InvalidOperationException("Aucun résultat n'a été renseigné");


            if (currentMatch.CreatorId != userMatricule && !currentMatch.Teams.SelectMany(t => t.Players).Select(p => p.Matricule).Contains(userMatricule))
                throw new InvalidOperationException("Seuls le créateur et les joueurs d'un match peuvent le clore");

            //suppression des équipes vides
            currentMatch.Teams.Where(t => t.Players.Count == 0).ToList().ForEach(t => _teamStore.SetState(t, EntityState.Deleted));

            currentMatch.Teams = currentMatch.Teams.Where(t => t.Players.Count > 0).ToList();
            if (currentMatch.Teams.Count < 2)
                throw new InvalidOperationException("Il faut au minimum 2 équipes pour clore un match");


            //calcul des scores
            var manches = new List<Dictionary<Team, int>>();
            foreach (string mancheString in match.Scores.Split(';').Where(s => !string.IsNullOrWhiteSpace(s)).ToList())
            {
                var score = new Dictionary<Team, int>();
                string[] scoreString = mancheString.Split('-');
                Team[] teams = currentMatch.Teams.ToArray();
                for (int i = 0; i < scoreString.Length; i++)
                {
                    if (currentMatch.Teams.Count < i)
                        continue;
                    var scores = scoreString[i].Split(':').Where(s => !string.IsNullOrWhiteSpace(s)).ToList();
                    var teamId = 0;
                    int.TryParse(scores[0], out teamId);
                    var result = 0;

                    var team = teams.FirstOrDefault(t => t.Id == teamId);
                    if (team != null && int.TryParse(scores[1], out result)) score.Add(team, result);
                }
                manches.Add(score);
            }

            if (manches.Count == 0)
                throw new InvalidOperationException("Il faut au minimum une manche de jouée pour clore un match");
            
            //selection du vainqueur, si vainqueur il y a:
            //L'équipe qui à le plus de manches gagnés

            //Si plusieurs vaiqueurs exaeco par manche: manche nulle
            var manchesGagnes = currentMatch.Teams.ToDictionary(t => t, t => 0);
            foreach (var equipes in manches.Select(m => m.Where(t => t.Value == m.Max(s => s.Value)).Select(t => t.Key).ToList()).Where(e => e.Count() == 1))
            {
                manchesGagnes[equipes.First()] += 1;
            }

            //Si plusieurs vainqueurs: égalité
            var victoiresMax = manchesGagnes.Max(m => m.Value);
            var manches2 = manchesGagnes.Where(t => t.Value.Equals(victoiresMax));
            var winners = manches2.Select(t => t.Key).ToList();
            if (winners.Count() == 1)
            {
                currentMatch.WinnerId = winners.First().Id;
                currentMatch.State = StateEnum.Won;
            }
            else
            {
                currentMatch.State = StateEnum.Draw;
            }

            currentMatch.CloseDate = DateTime.Now;
            currentMatch.Scores = match.Scores;

            //calculs des classements si le match est ranké
            if (currentMatch.Ranked)
            {
                Dictionary<Rank, double> eloResults =
                    currentMatch.Teams.SelectMany(t => t.Players).SelectMany(p => p.Ranks).Where(r => r.SportKey == currentMatch.SportKey).ToDictionary(t => t, t => 0.0d);

                int playersCount = eloResults.Count();
                if (playersCount == 0)
                    throw new InvalidOperationException("Aucun joueur ne participe à ce match");

                foreach (Team team in currentMatch.Teams)
                {
                    int teamId = team.Id;
                    List<Team> otherTeams = currentMatch.Teams.Where(t => t.Id != teamId).ToList();

                    int level1 = team.Players.Sum(p => p.Ranks.Where(r => r.SportKey == currentMatch.SportKey).Select(r => r.Level).FirstOrDefault())/team.Players.Count;

                    int level2 = otherTeams.Sum(t => t.Players.Sum(p => p.Ranks.Where(r => r.SportKey == currentMatch.SportKey).Select(r => r.Level).FirstOrDefault()))/
                                 otherTeams.Count();

                    int teamScore = (from manche in manches from score in manche where score.Key.Id == teamId select score.Value).Sum()/manches.Count();

                    foreach (Team otherTeam in otherTeams)
                    {
                        int otherTeamScore = (from manche in manches from score in manche where score.Key.Id == otherTeam.Id select score.Value).Sum()/manches.Count();

                        foreach (Player player in team.Players)
                        {
                            Rank playerRank = player.Ranks.FirstOrDefault(r => r.SportKey == currentMatch.SportKey);

                            if (playerRank == null) continue;

                            ResultatEnum matchState = currentMatch.State == StateEnum.Draw
                                ? ResultatEnum.Nul
                                : (currentMatch.WinnerId == team.Id) ? ResultatEnum.Victoire : ResultatEnum.Defaite;
                            eloResults[playerRank] += CalculateElo(player, level1, level2, teamScore, otherTeamScore, 1.0/otherTeams.Count, matchState);
                        }
                    }
                }

                //Maj du classement
                foreach (var eloResult in eloResults)
                {
                    eloResult.Key.Level += (int) Math.Round(eloResult.Value);
                }
            }

            await _matchStore.SaveChangesAsync();

            return await Task.FromResult(currentMatch);
        }
예제 #8
0
 public async Task<Match> Add(Match match)
 {
     _matchContext.Matches.Add(match);
     return await Task.FromResult(match);
 }
예제 #9
0
 public async Task<Match> SetState(Match match, EntityState entityState)
 {
     _matchContext.Entry(match).State = entityState;
     return await Task.FromResult(match);
 }
예제 #10
0
 public async Task<IHttpActionResult> Leave(Match match)
 {
     return Ok(MatchModel.From(await _matchBP.Leave(match, _userMatricule, _userMatricule)));
 }
예제 #11
0
 public async Task<IHttpActionResult> Join(Match match, int teamId )
 {
     return Ok(MatchModel.From(await _matchBP.Join(match, teamId, _userMatricule, _userMatricule)));
 }
예제 #12
0
 public async Task<IHttpActionResult> Post(Match match)
 {
     var newMatch = await _matchBP.Add(match, _userMatricule);
     return Ok(MatchModel.From(newMatch));
 }
예제 #13
0
 public async Task<IHttpActionResult> Put(int id, Match match)
 {
     var newMatch = await _matchBP.Update(match, _userMatricule);
     return Ok(MatchModel.From(newMatch));
 }
예제 #14
0
 public static MatchModel From(Match match)
 {
     if (match == null)
         return null;
     return new MatchModel
     {
         CreatorId = match.CreatorId,
         Creator = PlayerModel.From(match.Creator),
         Date = match.Date,
         CloseDate = match.CloseDate,
         Id = match.Id,
         Name = match.Name,
         Points = match.Points,
         Private = match.Private,
         Ranked = match.Ranked,
         Randomize = match.Randomize,
         SportKey = match.SportKey,
         WinnerId = match.WinnerId,
         Sleeves = match.Sleeves,
         Teams = match.Teams.Select(TeamModel.From).ToList(),
         State = match.State,
         Scores = match.Scores,
     };
 }