public RoundResultData GetRoundResult(string roundName, int pos, int nJudges) { RoundResultData rr = roundResults.Find(delegate(RoundResultData d) { return(d.Equals(roundName)); }); if (rr == null) { if (Role.IsJudge) { rr = new RoundResultData(roundName, pos); } else { rr = new RoundResultData(roundName, pos, nJudges); } rr.ClearStats(); roundResults.Add(rr); } else { // update judges... rr.SetNJudges(nJudges); } return(rr); }
public void SetRoom(string roundName, RoomData rd) { // this is not well-tested for awkward cases // visitedRooms should always have the same length as Tournament.I.Rounds, // (* still true? if Debater didn't participate in round, then RoomData.IsDummy is true if (rd == null) { visitedRooms.Remove(roundName); } else { visitedRooms[roundName] = rd.Index; } // delete RoundResults... if (rd == null || rd.IsDummy) { RoundResultData rr = roundResults.Find(delegate(RoundResultData d) { return(d.Equals(roundName)); }); if (rr != null) { Console.WriteLine("WARNING: Results removed for Round " + roundName + " (" + this + ")"); roundResults.Remove(rr); } } }
public string RoundResultsAsMarkup() { if (roundResults.Count == 0) { return("No Results"); } List <string> l = new List <string>(); if (Role.IsTeamMember) { l.Add("<i>Performance:</i> " + roundResults[0].PerformanceAsMarkup()); } else if (Role.IsJudge) { l.Add("<i>Average:</i> " + RoundResultData.JudgeStatsAsMarkup(statsAvg)); } foreach (RoundResultData rr in roundResults) { int roomIndex = GetRoomIndex(rr.RoundName); string room = roomIndex < 0 ? "?" : (roomIndex + 1).ToString(); l.Add(rr.RoundName + ", " + room + ": " + rr.AsMarkup()); } return(String.Join("\n", l.ToArray())); }
public static void UpdateStats() { // store for roundAvg, 0...8=speakers, 9/10=gov/opp Dictionary <string, List <int>[]> store1 = new Dictionary <string, List <int>[]>(); foreach (RoundData rd in Tournament.I.Rounds) { store1[rd.RoundName] = new List <int>[] { // eleven lists for 0...8, and teams new List <int>(), new List <int>(), new List <int>(), new List <int>(), new List <int>(), new List <int>(), new List <int>(), new List <int>(), new List <int>(), new List <int>(), new List <int>() }; } // stores for avgSpeaker/avgTeam Dictionary <Debater, List <double> > store2 = new Dictionary <Debater, List <double> >(); Dictionary <string, List <double> > store3 = new Dictionary <string, List <double> >(); foreach (Debater d in Tournament.I.Debaters) { if (d.Role.IsTeamMember) { foreach (RoundResultData rr in d.RoundResults) { List <int>[] val; if (store1.TryGetValue(rr.RoundName, out val)) { int pos = rr.GetPosition(); foreach (int p in rr.SpeakerScores) { if (p >= 0) { val[pos].Add(p); } } pos = (int)rr.Role + 9; foreach (int p in rr.TeamScores) { if (p >= 0) { val[pos].Add(p); } } } } // just init, used in following loops store2[d] = new List <double>(); store3[d.Role.TeamName] = new List <double>(); } // clear stats d.ClearResultStats(); } // calculate averages: per round and per position Dictionary <string, double[]> roundAvg = new Dictionary <string, double[]>(); foreach (string rN in store1.Keys) { roundAvg[rN] = new double[11]; // i iterates over positions and teams for (int i = 0; i < 11; i++) { roundAvg[rN][i] = OPDtabData.MiscHelpers.CalcExactAverage(store1[rN][i]); } } // collect performance of speaker/team per round foreach (Debater d in store2.Keys) { foreach (RoundResultData rr in d.RoundResults) { double[] val; if (roundAvg.TryGetValue(rr.RoundName, out val)) { int pos = rr.GetPosition(); double avg = OPDtabData.MiscHelpers.CalcExactAverage(rr.SpeakerScores); if (avg >= 0 && val[pos] >= 0) { store2[d].Add(avg - val[pos]); } pos = (int)rr.Role + 9; avg = OPDtabData.MiscHelpers.CalcExactAverage(rr.TeamScores); if (avg >= 0 && val[pos] >= 0) { store3[d.Role.TeamName].Add(avg - val[pos]); } } } } // calculate averages of performance, // is used to "predict" performance in selected round // compare it with result of judge Dictionary <RoundDebater, double> speakerAvg = new Dictionary <RoundDebater, double>(); Dictionary <string, double> teamAvg = new Dictionary <string, double>(); foreach (string t in store3.Keys) { teamAvg[t] = OPDtabData.MiscHelpers.CalcExactAverage(store3[t]); } foreach (Debater d in store2.Keys) { double avg = OPDtabData.MiscHelpers.CalcExactAverage(store2[d]); speakerAvg[new RoundDebater(d)] = avg; foreach (RoundResultData rr in d.RoundResults) { rr.Stats[0] = avg; rr.Stats[1] = teamAvg[d.Role.TeamName]; } } // iterate over rounds and rooms // and compare expected points with judge score // also save the calculated averages in round per position Dictionary <Debater, Dictionary <string, List <double>[]> > store4 = new Dictionary <Debater, Dictionary <string, List <double>[]> >(); foreach (RoundData rd in Tournament.I.Rounds) { // save the averages, is shown in ShowRanking double[] avgPoints; if (roundAvg.TryGetValue(rd.RoundName, out avgPoints)) { rd.AvgPoints = new List <double>(avgPoints); } // iterate over rooms foreach (RoomData room in rd.Rooms) { List <object> data = room.AsOrderedObjects(); foreach (RoundDebater j in room.Judges) { Debater judge = Tournament.I.FindDebater(j); if (judge == null) { continue; } RoundResultData rr = judge.RoundResults.Find(delegate(RoundResultData rr_) { return(rr_.Equals(rd.RoundName)); }); if (rr == null) { continue; } // init store4 on the fly Dictionary <string, List <double>[]> dic; if (!store4.TryGetValue(judge, out dic)) { dic = new Dictionary <string, List <double>[]>(); store4[judge] = dic; } List <double>[] list; if (!dic.TryGetValue(rd.RoundName, out list)) { list = new List <double>[] { new List <double>(), new List <double>() }; dic[rd.RoundName] = list; } for (int i = 0; i < 11; i++) { if (data[i] == null) { continue; } if (i < 9) { double correct; if (speakerAvg.TryGetValue((RoundDebater)data[i], out correct)) { double expected = correct + roundAvg[rd.RoundName][i]; int score = rr.SpeakerScores[i]; if (score < 0) { continue; } list[0].Add(score - expected); } } else { double correct; if (teamAvg.TryGetValue((data[i] as TeamData).TeamName, out correct)) { double expected = correct + roundAvg[rd.RoundName][i]; int score = rr.TeamScores[i - 9]; if (score < 0) { continue; } list[1].Add(score - expected); } } } } } } // the final result is the avg/sigma in store4 foreach (Debater d in store4.Keys) { foreach (string rN in store4[d].Keys) { double sum = 0; double sum2 = 0; foreach (double num in store4[d][rN][0]) { sum += num; sum2 += num * num; } int count = store4[d][rN][0].Count; double mu = count == 0?double.NaN:sum / count; double mu_err = count == 0?double.NaN: Math.Sqrt((sum2 / count - mu * mu) / count); // search roundResult and set stats foreach (RoundResultData rr in d.RoundResults) { if (rr.RoundName == rN) { rr.Stats[0] = mu; rr.Stats[1] = mu_err; rr.Stats[2] = OPDtabData.MiscHelpers.CalcExactAverage(store4[d][rN][1]); } } } // update averages d.UpdateStatsAvg(); } }