public void PostJsonLoading(FrcEvent e)
		{
			Event = e;

			foreach (TeamAnalysis ta in TeamData)
			{
				ta.PostJsonLoading(e);
			}

			foreach (MatchAnalysis ma in MatchData)
			{
				ma.PostJsonLoading(e);
			}
		}
		public EventAnalysis(FrcEvent frc) : this()
		{
			Event = frc;
			EventName = frc.EventName;

			foreach (Team t in frc.AllTeams)
			{
				TeamAnalysis ta = new TeamAnalysis(Event, t);
				ta.CalculateSafe();
				TeamData.Add(ta);
			}

			foreach (Match m in frc.Matches)
			{
				MatchAnalysis ma = new MatchAnalysis(Event, m, TeamData);
				ma.CalculatePregame();
				MatchData.Add(ma);
			}
		}
		/// <summary>
		/// Additional loading after deserialization
		/// </summary>
		/// <param name="e">Event to load data from</param>
		public void PostJsonLoading(FrcEvent e)
		{
			TrackedTeam = e.LoadTeam(TrackedTeamID);

			if (TeamDescription == null || TeamDescription == "")
			{
				TeamDescription = TrackedTeam.Description;
			}
			if (TeamExpectations == null || TeamExpectations == "")
			{
				TeamExpectations = TrackedTeam.Expectations;
			}
		}
		public MatchSetupWindow(FrcEvent frc, int lastMatchID, 
			bool cantTakeNoForAnAnswer) : base()
		{
			Settings = new LoadMatchSettings();
			Settings.Frc = frc;
			if (frc == null)
			{
				Settings.MatchID = 1;
			}
			else
			{
				Settings.MatchID = Math.Min(lastMatchID + 1, frc.Matches.Count - 1);
				Pregame = frc.LoadMatch(Settings.MatchID);
			}

			CantTakeNo = cantTakeNoForAnAnswer;

			InitializeComponent();
		}
		/// <summary>
		/// Additional loading to perform after deserialization from JSON
		/// </summary>
		/// <param name="e">FRC event to load from</param>
		public void PostJsonLoading(FrcEvent e)
		{
			BlamedTeam = e.LoadTeam(BlamedTeamID);
		}
Esempio n. 6
0
		/// <summary>
		/// Performs additional loading once deserialized from JSON
		/// </summary>
		/// <param name="e">Event to create references from</param>
		public void PostJsonLoading(FrcEvent e)
		{
			if (ScoringTeamID.HasValue)
			{
				ScoringTeam = e.LoadTeam(ScoringTeamID.Value);
			}
			else
			{
				ScoringTeam = null;
			}
		}
		public NewMatchDialog(FrcEvent e)
		{
			frc = e;
			InitializeComponent();
		}
		/// <summary>
		/// Instantiates an analysis object
		/// </summary>
		/// <param name="e">Host event</param>
		/// <param name="linked">Corresponding team</param>
		public TeamAnalysis(FrcEvent e, Team linked)
		{
			Event = e;
			Team = linked;
		}
		public void PostJsonLoading(FrcEvent e)
		{
			Team = e.LoadTeam(TeamID);
			Match = e.LoadMatch(MatchID);
		}
		/// <summary>
		/// Instantiates a match analysis object with pregame analysis done.
		/// </summary>
		/// <param name="frc">Host event</param>
		/// <param name="m">Corresponding match</param>
		/// <param name="analyses">List of team analyses</param>
		public MatchAnalysis(FrcEvent frc, Match m, List<TeamAnalysis> analyses)
		{
			Event = frc;
			Match = m;
			TeamAnalyses = analyses;
			Pregame = m.Pregame;
			CalculatePregame();
		}
		/// <summary>
		/// Forms a match from recorded data
		/// </summary>
		/// <param name="frc">Event to load additional data from</param>
		/// <param name="redData">Group of recordings from red's data</param>
		/// <param name="blueData">Group of recordings from blue's data</param>
		/// <returns></returns>
		public static Match FormMatch(FrcEvent frc,
			AllianceGroup<RecordedMatch> redData, 
			AllianceGroup<RecordedMatch> blueData)
		{
			// Team data count (reliability)
			int redTeamsCount = redData.Count((rec) => rec != null);
			int blueTeamsCount = blueData.Count((rec) => rec != null);
			if (redTeamsCount + blueTeamsCount < 3 ||
				redTeamsCount == 0 || blueTeamsCount == 0) // not enough data
			{
				return null; // Give up
			}

			Alliance red = new Alliance(redData.A.TrackedTeam, 
				redData.B.TrackedTeam, redData.C.TrackedTeam);
			Alliance blue = new Alliance(blueData.A.TrackedTeam,
				blueData.B.TrackedTeam, blueData.C.TrackedTeam);
			
			List<RecordedMatch> allData = new List<RecordedMatch>();
			foreach (RecordedMatch rec in redData)
			{
				allData.Add(rec);
			}
			foreach (RecordedMatch rec in blueData)
			{
				allData.Add(rec);
			}

			// MATCH ID (quadruple lambda!)
			int matchID = allData.ConvertAll<int>((rec) => rec.MatchNumber).Mode((modes) =>
			{
				try
				{
					return modes.First((n) =>
					{
						return !(frc.Matches.Exists((m) => m.Number == n && !m.Pregame));
					});
				}
				catch (InvalidOperationException)
				{
					Util.DebugLog(LogLevel.Warning, "SYNC", 
						"Completed match with this ID is already present in event");
					return modes.First();
				}
			});

			Match result = new Match(matchID, blue, red);
			result.Pregame = false;

			// This section is because Unprocessed and Landfill Litter type goals are shared, but
			// come more than one per match.
			double dRedLfLitter = redData.ToList().ConvertAll<int>((rec) => rec.ScoredGoals.Count(
				(g) => g.Type == GoalType.LandfillLitter)).Mean();
			int nRedLfLitter = (int)dRedLfLitter;
			double dRedUnpLitter = redData.ToList().ConvertAll<int>((rec) => rec.ScoredGoals.Count(
				(g) => g.Type == GoalType.UnprocessedLitter)).Mean();
			int nRedUnpLitter = (int)dRedUnpLitter;
			
			double dBlueLfLitter = blueData.ToList().ConvertAll<int>((rec) => rec.ScoredGoals.Count(
				(g) => g.Type == GoalType.UnprocessedLitter)).Mean();
			int nBlueLfLitter = (int)dBlueLfLitter;
			double dBlueUnpLitter = blueData.ToList().ConvertAll<int>((rec) => rec.ScoredGoals.Count(
				(g) => g.Type == GoalType.UnprocessedLitter)).Mean();
			int nBlueUnpLitter = (int)dBlueUnpLitter;

			// GOALS LIST
			List<Goal> goals = new List<Goal>();
			goals.Sort((g1, g2) => g1.TimeScoredInt - g2.TimeScoredInt);
			foreach (RecordedMatch rec in allData)
			{
				foreach (Goal addedGoal in rec.ScoredGoals)
				{
					#region add by goal type
					switch (addedGoal.Type)
					{
					#region RobotSet
					case GoalType.RobotSet:
						bool alreadyHasRobotSet = goals.Exists((g) => 
						{
							return g.Type == GoalType.RobotSet &&
								g.ScoringAlliance == addedGoal.ScoringAlliance;
						});

						if (!alreadyHasRobotSet)
						{
							goals.Add(addedGoal);
						}
						break;
					#endregion
					#region YellowToteSet
					case GoalType.YellowToteSet:
						bool alreadyHasYTS = goals.Exists((g) => 
						{
							return g.Type == GoalType.YellowToteSet &&
								g.ScoringAlliance == addedGoal.ScoringAlliance;
						});

						if (!alreadyHasYTS)
						{
							goals.Add(addedGoal);
						}
						break;
					#endregion
					#region ContainerSet
					case GoalType.ContainerSet:
						bool alreadyHasContainerSet = goals.Exists((g) =>
						{
							return g.Type == GoalType.ContainerSet &&
								g.ScoringAlliance == addedGoal.ScoringAlliance;
						});

						if (!alreadyHasContainerSet)
						{
							goals.Add(addedGoal);
						}
						break;
					#endregion
					#region Coopertition
					case GoalType.Coopertition:
						bool alreadyHasCoopertition = goals.Exists((g) =>
						{
							return g.Type == GoalType.Coopertition;
						});

						if (!alreadyHasCoopertition)
						{
							goals.Add(addedGoal);
						}
						break;
					#endregion
					case GoalType.GrayTote:
						goals.Add(addedGoal);
						break;
					case GoalType.ContainerTeleop:
						goals.Add(addedGoal);
						break;
					case GoalType.RecycledLitter:
						goals.Add(addedGoal);
						break;
					default:
						break;
					}
					#endregion
				}
			}

			for (int i = 0; i < nRedLfLitter; i++)
			{
				goals.Add(Goal.MakeLandfillLitter(AllianceColor.Red));
			}
			for (int i = 0; i < nRedUnpLitter; i++)
			{
				goals.Add(Goal.MakeUnprocessedLitter(AllianceColor.Red));
			}

			for (int i = 0; i < nBlueLfLitter; i++)
			{
				goals.Add(Goal.MakeLandfillLitter(AllianceColor.Blue));
			}
			for (int i = 0; i < nBlueUnpLitter; i++)
			{
				goals.Add(Goal.MakeUnprocessedLitter(AllianceColor.Blue));
			}

			result.Goals = goals;

			// PENALTIES
			List<Penalty> penalties = new List<Penalty>();
			foreach (RecordedMatch rec in allData)
			{
				foreach (Penalty pen in rec.AlliancePenalties)
				{
					bool nearbyPenalty = penalties.Exists((p) =>
					{
						return Math.Abs(p.TimeOfPenaltyInt - pen.TimeOfPenaltyInt) < PENALTY_THRESHOLD;
					});

					if (!nearbyPenalty)
					{
						penalties.Add(pen);
					}
				}
			}
			result.Penalties = penalties;

			List<Goal> redGoals = result.RedGoals;
			int redGoalScore = redGoals.Aggregate(0, (total, g) => total + g.PointValue());
			redGoalScore = result.RedPenalties.Aggregate(redGoalScore, (total, p) => total + p.ScoreChange());
			List<Goal> blueGoals = result.BlueGoals;
			int blueGoalScore = blueGoals.Aggregate(0, (total, g) => total + g.PointValue());
			blueGoalScore = result.BluePenalties.Aggregate(blueGoalScore, (total, p) => total + p.ScoreChange());
			
			// WINNER
			List<AllianceColor> winnerRecords = allData.ConvertAll<AllianceColor>((rec) => rec.Winner);
			AllianceColor winner = winnerRecords.Mode((modes) => redGoalScore > blueGoalScore ? 
				AllianceColor.Red : AllianceColor.Blue); // Incredibly unlikely
			result.Winner = winner;

			// WORKING
			result.RedWorking = new AllianceGroup<bool>();
			result.RedWorking.A = redData.A != null ? redData.A.Working : true;
			result.RedWorking.B = redData.B != null ? redData.B.Working : true;
			result.RedWorking.C = redData.C != null ? redData.C.Working : true;
			result.BlueWorking = new AllianceGroup<bool>();
			result.BlueWorking.A = blueData.A != null ? blueData.A.Working : true;
			result.BlueWorking.B = blueData.B != null ? blueData.B.Working : true;
			result.BlueWorking.C = blueData.C != null ? blueData.C.Working : true;

			// DEFENSE
			result.RedDefense = new AllianceGroup<int>();
			result.RedDefense.A = redData.A != null ? redData.A.Defense : 5;
			result.RedDefense.B = redData.B != null ? redData.B.Defense : 5;
			result.RedDefense.C = redData.C != null ? redData.C.Defense : 5;
			result.BlueDefense = new AllianceGroup<int>();
			result.BlueDefense.A = blueData.A != null ? blueData.A.Defense : 5;
			result.BlueDefense.B = blueData.B != null ? blueData.B.Defense : 5;
			result.BlueDefense.C = blueData.C != null ? blueData.C.Defense : 5;

			// DISCREPANCY POINTS
			int finalScoreRed = (int)redData.ToList().ConvertAll<int>((rec) => rec.AllianceFinalScore).Mean();
			int finalScoreBlue = (int)blueData.ToList().ConvertAll<int>((rec) => rec.AllianceFinalScore).Mean(); // round down
			result.RedFinalScore = finalScoreRed;
			result.BlueFinalScore = finalScoreBlue;

			int dpRed = finalScoreRed - redGoalScore;
			int dpBlue = finalScoreBlue - blueGoalScore;
			result.RedDiscrepancyPoints = dpRed;
			result.BlueDiscrepancyPoints = dpBlue;

			return result;
		}
		/// <summary>
		/// Adjusts team info from recorded match
		/// </summary>
		/// <param name="frc"></param>
		/// <param name="data"></param>
		public static void AdjustTeamInfo(FrcEvent frc, RecordedMatch data)
		{
			Team t = frc.LoadTeam(data.TrackedTeamID);
			t.Description = data.TeamDescription;
			t.Expectations = data.TeamExpectations;
		}
		/// <summary>
		/// Merges match recordings together after deserialization
		/// </summary>
		/// <param name="frc">Event to load data from</param>
		/// <param name="redA">Team A on Red</param>
		/// <param name="redB">Team B on Red</param>
		/// <param name="redC">Team C on Red</param>
		/// <param name="blueA">Team A on Blue</param>
		/// <param name="blueB">Team B on Blue</param>
		/// <param name="blueC">Team C on Blue</param>
		/// <returns></returns>
		public static Match Merge(FrcEvent frc, RecordedMatch redA, RecordedMatch redB, RecordedMatch redC,
			RecordedMatch blueA, RecordedMatch blueB, RecordedMatch blueC)
		{
			redA.PostJsonLoading(frc);
			redB.PostJsonLoading(frc);
			redC.PostJsonLoading(frc);
			blueA.PostJsonLoading(frc);
			blueB.PostJsonLoading(frc);
			blueC.PostJsonLoading(frc);

			AllianceGroup<RecordedMatch> red = new AllianceGroup<RecordedMatch>(redA, redB, redC);
			AllianceGroup<RecordedMatch> blue = new AllianceGroup<RecordedMatch>(blueA, blueB, blueC);

			return FormMatch(frc, red, blue);
		}
		public static void SaveEvent(FrcEvent frc, string path)
		{
			Initialize(false);

			string contents = JsonConvert.SerializeObject(frc, Formatting.Indented);
			File.WriteAllText(path, contents);
		}
		/// <summary>
		/// Completes any references left out when loaded by JSON
		/// </summary>
		/// <param name="e"></param>
		public void PostJsonLoading(FrcEvent e)
		{
			Event = e;
			Team = e.LoadTeam(TeamID);
		}
		/// <summary>
		/// Loads the match after instantiated by JSON.
		/// </summary>
		/// <param name="e">Event to load the rest of the match from</param>
		public void PostJsonLoading(FrcEvent e)
		{
			Event = e;
			Match = e.LoadMatch(MatchID);
		}
		public void NewEvent()
		{
			NewEventDialog ned = new NewEventDialog(EventPath);
			bool? res = ned.ShowDialog();

			if (res == true) // Nullable<bool>
			{
				MessageBoxResult mbr = MessageBox.Show(
					"Do you want to save this event before creating a new one?",
					"Save Event", MessageBoxButton.YesNoCancel);

				if (mbr == MessageBoxResult.Yes)
				{
					SaveAll();
				}
				else if (mbr == MessageBoxResult.Cancel)
				{
					return;
				}

				FrcEvent frc = new FrcEvent(ned.EventName);
				Event = frc;
				ScoutingJson.SaveEvent(Event, ned.Path);
				EventPath = ned.Path;

				if (teamsList != null)
				{
					Event.PostJsonLoading(teamsList);
				}
			}
		}
Esempio n. 18
0
		/// <summary>
		/// Additional loading once deserialization is complete
		/// </summary>
		/// <param name="e">Event to load data from</param>
		public void PostJsonLoading(FrcEvent e)
		{
			BlueAlliance.PostJsonLoading(e);
			RedAlliance.PostJsonLoading(e);

			if (!Pregame)
			{
				foreach (Goal g in Goals)
				{
					g.PostJsonLoading(e);
				}
			}
		}
		/// <summary>
		/// Do not use. May be deleted in the future.
		/// </summary>
		/// <param name="e">Analysis for teams</param>
		public TeamAnalysis(FrcEvent e) : this(e, null)
		{ }