private RankingList GetUnsortedList(IEnumerable <long> teamIds, DateTime upperDateLimit, out DateTime lastUpdatedOn) { lastUpdatedOn = DateTime.UtcNow; if (MatchesPlayed.Any()) { lastUpdatedOn = MatchesPlayed .Where(m => teamIds.Contains(m.HomeTeamId) || teamIds.Contains(m.GuestTeamId)) .Max(m => m.ModifiedOn); } else if (MatchesToPlay.Any()) { lastUpdatedOn = MatchesToPlay .Where(m => teamIds.Contains(m.HomeTeamId) || teamIds.Contains(m.GuestTeamId)) .Max(m => m.ModifiedOn); } var rankingList = new RankingList { UpperDateLimit = upperDateLimit, LastUpdatedOn = lastUpdatedOn }; foreach (var teamId in teamIds) { var rank = new Rank { Number = -1, TeamId = teamId, MatchesPlayed = MatchesPlayed.Count(m => m.HomeTeamId == teamId || m.GuestTeamId == teamId), MatchesToPlay = MatchesToPlay.Count(m => m.HomeTeamId == teamId || m.GuestTeamId == teamId) }; // upperDateLimit contains the date part (without time), so the MatchDate must also be compared with the date part! foreach (var match in MatchesPlayed.Where(m => (m.HomeTeamId == teamId || m.GuestTeamId == teamId) && m.MatchDate.HasValue && m.MatchDate.Value.Date <= upperDateLimit.Date)) { if (match.HomeTeamId == teamId) { rank.MatchPoints.Home += match.HomeMatchPoints ?? 0; rank.MatchPoints.Guest += match.GuestMatchPoints ?? 0; rank.SetPoints.Home += match.HomeSetPoints ?? 0; rank.SetPoints.Guest += match.GuestSetPoints ?? 0; rank.BallPoints.Home += match.HomeBallPoints ?? 0; rank.BallPoints.Guest += match.GuestBallPoints ?? 0; rank.MatchesWonAndLost.Home += match.HomeMatchPoints > match.GuestMatchPoints ? 1 : 0; rank.MatchesWonAndLost.Guest += match.HomeMatchPoints < match.GuestMatchPoints ? 1 : 0; } else { rank.MatchPoints.Home += match.GuestMatchPoints ?? 0; rank.MatchPoints.Guest += match.HomeMatchPoints ?? 0; rank.SetPoints.Home += match.GuestSetPoints ?? 0; rank.SetPoints.Guest += match.HomeSetPoints ?? 0; rank.BallPoints.Home += match.GuestBallPoints ?? 0; rank.BallPoints.Guest += match.HomeBallPoints ?? 0; rank.MatchesWonAndLost.Home += match.HomeMatchPoints < match.GuestMatchPoints ? 1 : 0; rank.MatchesWonAndLost.Guest += match.HomeMatchPoints > match.GuestMatchPoints ? 1 : 0; } } rankingList.Add(rank); } return(rankingList); }
public int Compare(Rank x, Rank y) { if (Ranking is null) { throw new NullReferenceException("Ranking property must not be null"); } if (x == null || y == null) { throw new NullReferenceException($"{nameof(Rank)} arguments must not be null"); } // sort down teams with no matches played if (x.MatchesPlayed == 0) { return(1); } if (y.MatchesPlayed == 0) { return(-1); } // sort down overruled results with no points at all if (x.MatchPoints.Home + x.MatchPoints.Guest + x.SetPoints.Home + x.SetPoints.Guest + x.BallPoints.Home + x.BallPoints.Guest == 0) { return(1); } if (y.MatchPoints.Home + y.MatchPoints.Guest + y.SetPoints.Home + y.SetPoints.Guest + y.BallPoints.Home + y.BallPoints.Guest == 0) { return(-1); } if ((x.MatchPoints.Home - x.MatchPoints.Guest) < (y.MatchPoints.Home - y.MatchPoints.Guest)) { return(1); } else if ((x.MatchPoints.Home - x.MatchPoints.Guest) > (y.MatchPoints.Home - y.MatchPoints.Guest)) { return(-1); } if ((x.SetPoints.Home - x.SetPoints.Guest) < (y.SetPoints.Home - y.SetPoints.Guest)) { return(1); } else if ((x.SetPoints.Home - x.SetPoints.Guest) > (y.SetPoints.Home - y.SetPoints.Guest)) { return(-1); } if ((x.BallPoints.Home - x.BallPoints.Guest) < (y.BallPoints.Home - y.BallPoints.Guest)) { return(1); } else if ((x.BallPoints.Home - x.BallPoints.Guest) > (y.BallPoints.Home - y.BallPoints.Guest)) { return(-1); } // avoid an infinite loop if (!_directCompareRankingInProgress && x.MatchesPlayed > 0 && y.MatchesPlayed > 0) { _directCompareRankingInProgress = true; var directCompareRanking = Ranking.GetList(new[] { x.TeamId, y.TeamId }, UpperDateLimit); _directCompareRankingInProgress = false; if (directCompareRanking[0].TeamId == x.TeamId) { return(-1); } else { return(1); } } else { // if directCompareRanking is reached twice, both teams must have the same score, // so we return a random winner by comparing Team Ids return(x.TeamId < y.TeamId ? 1 : -1); } }
public int Compare(Rank x, Rank y) { /* * BVV-Spielordnung * Stand: 25.11.05 * http://bvv.volley.de/n/fileadmin/user_all/Download/Ordnungen/spielordnung25112005.pdf * * 11. Spielwertung, Nichtantreten von Mannschaften * 11.1 a) Alle Pflichtspiele sind über 3 Gewinnsätze auszutragen. * b) Meisterschaftsspiele der Altersklassen und Pokalspiele bis Bezirksebene können * über 2 Gewinnsätze ausgetragen werden. Eine bindende Festlegung trifft * der jeweils zuständige Spielausschuss. * 11.2 a) Zur Ermittlung der Rangfolge in Spielrunden und bei Turnieren erhalten gewinnende * Mannschaften zwei Pluspunkte (2:0), verlierende Mannschaften zwei * Minuspunkte (0:2). Die Mannschaft, die mehr Pluspunkte aufweist, erhält den * besseren Platz. Bei gleicher Punktzahl ist besser platziert, wer weniger Minuspunkte * aufweist. * b) Bei Punktgleichheit von zwei oder mehr Mannschaften entscheidet über die * Platzierung zunächst die Satzdifferenz (Subtraktionsverfahren). Bei gleicher * Satzdifferenz zählt die Anzahl der gewonnenen Sätze. * c) Bei Punktgleichheit, gleicher Satzdifferenz und gleicher Anzahl der gewonnenen * Sätze von zwei oder mehr Mannschaften entscheidet über die Platzierung * die Balldifferenz (Subtraktionsverfahren). Bei gleicher Balldifferenz zählt die * Anzahl der gewonnenen Bälle. * d) Er gibt sich nach Anwendung der Absätze a) bis c) ein Gleichstand für zwei * oder mehr Mannschaften, müssen diese Mannschaften nochmals gegeneinander * spielen; die Entscheidungsspiele sind dann maßgebend für die Platzierung. * Solche Entscheidungsspiele sollen auf neutralen Plätzen stattfinden. */ if (x == null || y == null) { throw new NullReferenceException($"{nameof(Rank)} arguments must not be null"); } // sort down teams with no matches played if (x.MatchesPlayed == 0) { return(1); } if (y.MatchesPlayed == 0) { return(-1); } // sort down overruled results with no points at all if (x.MatchPoints.Home + x.MatchPoints.Guest + x.SetPoints.Home + x.SetPoints.Guest + x.BallPoints.Home + x.BallPoints.Guest == 0) { return(1); } if (y.MatchPoints.Home + y.MatchPoints.Guest + y.SetPoints.Home + y.SetPoints.Guest + y.BallPoints.Home + y.BallPoints.Guest == 0) { return(-1); } // a) if (x.MatchPoints.Home < y.MatchPoints.Home) { return(1); } else if (x.MatchPoints.Home > y.MatchPoints.Home) { return(-1); } if (x.MatchPoints.Guest > y.MatchPoints.Guest) { return(1); } else if (x.MatchPoints.Guest < y.MatchPoints.Guest) { return(-1); } // b) if ((x.SetPoints.Home - x.SetPoints.Guest) < (y.SetPoints.Home - y.SetPoints.Guest)) { return(1); } else if ((x.SetPoints.Home - x.SetPoints.Guest) > (y.SetPoints.Home - y.SetPoints.Guest)) { return(-1); } if (x.SetPoints.Home < y.SetPoints.Home) { return(1); } else if (x.SetPoints.Home > y.SetPoints.Home) { return(-1); } // c) if ((x.BallPoints.Home - x.BallPoints.Guest) < (y.BallPoints.Home - y.BallPoints.Guest)) { return(1); } else if ((x.BallPoints.Home - x.BallPoints.Guest) > (y.BallPoints.Home - y.BallPoints.Guest)) { return(-1); } if (x.BallPoints.Home < y.BallPoints.Home) { return(1); } else if (x.BallPoints.Home > y.BallPoints.Home) { return(-1); } // d) taking already played matches instead of new match to play // avoid an infinite loop if (!_directCompareRankingInProgress && x.MatchesPlayed > 0 && y.MatchesPlayed > 0) { _directCompareRankingInProgress = true; var directCompareRanking = Ranking.GetList(new[] { x.TeamId, y.TeamId }, UpperDateLimit); _directCompareRankingInProgress = false; if (directCompareRanking[0].TeamId == x.TeamId) { return(-1); } else { return(1); } } else { // if directCompareRanking is reached twice, both teams must have the same score, // so we return a random winner by comparing Team Ids return(x.TeamId < y.TeamId ? 1 : -1); } }
public int Compare(Rank x, Rank y) { if (UpperDateLimit == null) { throw new NullReferenceException($"{nameof(UpperDateLimit)} cannot be null."); } if (Ranking == null) { throw new NullReferenceException($"{nameof(Ranking)} cannot be null."); } /* * BVV-Spielordnung * Stand: 28.06.2019 * http://www.volleyball-bayern.de/fileadmin/user_upload/Bezirke/Niederbayern/Spielwesen/VSPO_2019.pdf * * 11.2 * * a) Zur Ermittlung der Rangfolge in Spielrunden und bei Turnieren erhalten * - bei Spielen über 3 Gewinnsätze * der Gewinner bei einem 3:0 oder 3:1 drei Punkte, * der Gewinner bei einem 3:2 zwei Punkte und der Verlierer einen Punkt. * Der Verlierer erhält bei einem 1:3 oder 0:3 keinen Punkt. * Es werden nur Pluspunkte vergeben. * Über die Rangfolge von zwei oder mehr Mannschaften entscheidet in absteigender Priorität * a1) die Anzahl der Punkte, * a2) die Anzahl gewonnener Spiele, * a3) der Satzquotient, indem die Anzahl der gewonnenen Sätze durch die Anzahl der verlorenen Sätze dividiert wird, * a4) der Ballpunktquotient, indem die Anzahl der gewonnenen Ballpunkte durch die Anzahl der verlorenen Ballpunkte dividiert wird, * a5) der direkte Vergleich zwischen den Mannschaften, wobei die Kriterien nach a1) bis a4) zur Berechnung der Rangfolge herangezogen werden. * Ergibt sich nach Anwendung der Ziffern a1) bis a5) ein Gleichstand für zwei oder mehr Mannschaften, müssen diese Mannschaften nochmals gegeneinander spielen; die Entscheidungsspiele sind dann maßgebend für die Platzierung. Solche Entscheidungsspiele sollen auf neutralen Plätzen stattfinden. Bei Turnieren kann in der Ausschreibung eine hiervon abweichende Regelung getroffen werden. * * b) Zur Ermittlung der Rangfolge in Spielrunden und bei Turnieren erhalten * - bei Spielen über 2 Gewinnsätze * der Gewinner bei einem 2:0 oder 2:1 zwei Punkte, der Verlierer keinen Punkt. * Es werden nur Pluspunkte vergeben. * Über die Rangfolge von zwei oder mehr Mannschaften entscheidet in absteigender Priorität * b1) die Anzahl der Punkte, * b2) die Satzdifferenz, indem die Anzahl der verlorenen Sätze von der Anzahl der gewonnenen Sätze subtrahiert wird, * b3) bei gleicher Satzdifferenz die Anzahl der gewonnenen Sätze, * b4) die Ballpunktdifferenz, indem die Anzahl der verlorenen Bälle von der Anzahl der gewonnenen Bälle subtrahiert wird, * b5) bei gleicher Balldifferenz die Anzahl der gewonnenen Bälle. * Ergibt sich nach Anwendung der Ziffern b1) bis b5) ein Gleichstand für zwei oder mehr Mannschaften, müssen diese Mannschaften nochmals gegeneinander spielen; die Entscheidungsspiele sind dann maßgebend für die Platzierung. Solche Entscheidungsspiele sollen auf neutralen Plätzen stattfinden. Bei Turnieren kann in der Ausschreibung eine hiervon abweichende Regelung getroffen werden. */ if (x == null || y == null) { throw new NullReferenceException($"{nameof(Rank)} arguments must not be null"); } // sort down teams with no matches played if (x.MatchesPlayed == 0) { return(1); } if (y.MatchesPlayed == 0) { return(-1); } // sort down overruled results with no points at all if (x.MatchPoints.Home + x.MatchPoints.Guest + x.SetPoints.Home + x.SetPoints.Guest + x.BallPoints.Home + x.BallPoints.Guest == 0) { return(1); } if (y.MatchPoints.Home + y.MatchPoints.Guest + y.SetPoints.Home + y.SetPoints.Guest + y.BallPoints.Home + y.BallPoints.Guest == 0) { return(-1); } // a) if (x.MatchPoints.Home < y.MatchPoints.Home) { return(1); } else if (x.MatchPoints.Home > y.MatchPoints.Home) { return(-1); } if (x.MatchPoints.Guest > y.MatchPoints.Guest) { return(1); } else if (x.MatchPoints.Guest < y.MatchPoints.Guest) { return(-1); } // b) if ((x.SetPoints.Home - x.SetPoints.Guest) < (y.SetPoints.Home - y.SetPoints.Guest)) { return(1); } else if ((x.SetPoints.Home - x.SetPoints.Guest) > (y.SetPoints.Home - y.SetPoints.Guest)) { return(-1); } if (x.SetPoints.Home < y.SetPoints.Home) { return(1); } else if (x.SetPoints.Home > y.SetPoints.Home) { return(-1); } // c) if ((x.BallPoints.Home - x.BallPoints.Guest) < (y.BallPoints.Home - y.BallPoints.Guest)) { return(1); } else if ((x.BallPoints.Home - x.BallPoints.Guest) > (y.BallPoints.Home - y.BallPoints.Guest)) { return(-1); } if (x.BallPoints.Home < y.BallPoints.Home) { return(1); } else if (x.BallPoints.Home > y.BallPoints.Home) { return(-1); } // d) taking already played matches instead of new match to play // avoid an infinite loop if (!_directCompareRankingInProgress && x.MatchesPlayed > 0 && y.MatchesPlayed > 0) { _directCompareRankingInProgress = true; var directCompareRanking = Ranking.GetList(new[] { x.TeamId, y.TeamId }, UpperDateLimit); _directCompareRankingInProgress = false; if (directCompareRanking[0].TeamId == x.TeamId) { return(-1); } else { return(1); } } else { // if directCompareRanking is reached twice, both teams must have the same score, // so we return a random winner by comparing Team Ids return(x.TeamId < y.TeamId ? 1 : -1); } }