[longomatch] Add stats for game units
- From: Andoni Morales Alastruey <amorales src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [longomatch] Add stats for game units
- Date: Mon, 6 Feb 2012 02:13:35 +0000 (UTC)
commit 80cd0504ce810ae57a4d13b37ee24e9cd5ec6a55
Author: Andoni Morales Alastruey <ylatuya gmail com>
Date: Mon Feb 6 03:03:55 2012 +0100
Add stats for game units
LongoMatch.Core/LongoMatch.Core.mdp | 2 +
LongoMatch.Core/Makefile.am | 2 +
LongoMatch.Core/Stats/GameUnitStats.cs | 121 +++++++++++++++++++++++++++++++
LongoMatch.Core/Stats/GameUnitsStats.cs | 94 ++++++++++++++++++++++++
LongoMatch.Core/Stats/ProjectStats.cs | 20 +++++-
5 files changed, 237 insertions(+), 2 deletions(-)
---
diff --git a/LongoMatch.Core/LongoMatch.Core.mdp b/LongoMatch.Core/LongoMatch.Core.mdp
index 698b899..83cb0b7 100644
--- a/LongoMatch.Core/LongoMatch.Core.mdp
+++ b/LongoMatch.Core/LongoMatch.Core.mdp
@@ -96,6 +96,8 @@
<File subtype="Code" buildaction="Compile" name="Stats/Stat.cs" />
<File subtype="Code" buildaction="Compile" name="Stats/SubCategoryStat.cs" />
<File subtype="Code" buildaction="Compile" name="Stats/PlayersStats.cs" />
+ <File subtype="Code" buildaction="Compile" name="Stats/GameUnitStats.cs" />
+ <File subtype="Code" buildaction="Compile" name="Stats/GameUnitsStats.cs" />
</Contents>
<References>
<ProjectReference type="Gac" localcopy="True" refto="System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
diff --git a/LongoMatch.Core/Makefile.am b/LongoMatch.Core/Makefile.am
index e248df0..f8e46b0 100644
--- a/LongoMatch.Core/Makefile.am
+++ b/LongoMatch.Core/Makefile.am
@@ -41,6 +41,8 @@ SOURCES = \
Interfaces/ITemplatesService.cs \
Interfaces/ITimelineNode.cs \
Stats/CategoryStats.cs \
+ Stats/GameUnitStats.cs \
+ Stats/GameUnitsStats.cs \
Stats/PercentualStat.cs \
Stats/PlayersStats.cs \
Stats/ProjectStats.cs \
diff --git a/LongoMatch.Core/Stats/GameUnitStats.cs b/LongoMatch.Core/Stats/GameUnitStats.cs
new file mode 100644
index 0000000..dc93374
--- /dev/null
+++ b/LongoMatch.Core/Stats/GameUnitStats.cs
@@ -0,0 +1,121 @@
+//
+// Copyright (C) 2012 Andoni Morales Alastruey
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using LongoMatch.Store;
+
+namespace LongoMatch.Stats
+{
+ public class GameUnitStatsNode : List<GameUnitStatsNode>
+ {
+ public GameUnitStatsNode (TimelineNode node)
+ {
+ Node = node;
+ }
+
+ public GameUnitStatsNode (TimelineNode node, List<GameUnitStatsNode> list): base (list)
+ {
+ Node = node;
+ }
+
+ public TimelineNode Node {
+ get;
+ set;
+ }
+
+ public string Name {
+ get {
+ return Node.Name;
+ }
+ }
+
+ public int Duration {
+ get {
+ return Node.Duration.MSeconds;
+ }
+ }
+
+ public int PlayingTime {
+ get {
+ if (this.Count == 0) {
+ return Duration;
+ }
+ return this.Sum(n => n.PlayingTime);
+ }
+ }
+
+ public int PausedTime {
+ get {
+ if (this.Count == 0)
+ return 0;
+ return Duration - PlayingTime;
+ }
+ }
+
+ public double AverageDuration {
+ get {
+ if (this.Count == 0)
+ return 0;
+ return this.Average(n => n.Duration);
+ }
+ }
+
+ public double AveragePlayingTime {
+ get {
+ if (this.Count == 0)
+ return 0;
+ return this.Average(n => n.PlayingTime);
+ }
+ }
+
+ public double AveragePausedTime {
+ get {
+ if (this.Count == 0)
+ return 0;
+ return this.Average(n => n.PausedTime);
+ }
+ }
+
+ public double DurationTimeStdDeviation {
+ get {
+ if (this.Count == 0)
+ return 0;
+ return Math.Sqrt(this.Average(n=>Math.Pow(n.Duration - AverageDuration,2)));
+ }
+ }
+
+ public double PlayingTimeStdDeviation {
+ get {
+ if (this.Count == 0)
+ return 0;
+ return Math.Sqrt(this.Average(n=>Math.Pow(n.PlayingTime - AveragePlayingTime,2)));
+ }
+ }
+
+ public double PausedTimeStdDeviation {
+ get {
+ if (this.Count == 0)
+ return 0;
+ return Math.Sqrt(this.Average(n=>Math.Pow(n.PausedTime - AveragePausedTime,2)));
+ }
+ }
+ }
+}
+
diff --git a/LongoMatch.Core/Stats/GameUnitsStats.cs b/LongoMatch.Core/Stats/GameUnitsStats.cs
new file mode 100644
index 0000000..03db35a
--- /dev/null
+++ b/LongoMatch.Core/Stats/GameUnitsStats.cs
@@ -0,0 +1,94 @@
+//
+// Copyright (C) 2012 Andoni Morales Alastruey
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using LongoMatch.Store;
+
+namespace LongoMatch.Stats
+{
+ public class GameUnitsStats
+ {
+ TimelineNode game;
+ GameUnitStatsNode gameNode;
+ Dictionary<GameUnit, GameUnitStatsNode> gameUnitNodes;
+
+ const float MAX_DIFF = (float) 80 / 100;
+
+ public GameUnitsStats (GameUnitsList guList, int duration)
+ {
+ game = new TimelineNode{Start=new Time(0), Stop=new Time(duration)};
+ gameNode = new GameUnitStatsNode(game);
+ gameUnitNodes = new Dictionary<GameUnit, GameUnitStatsNode>();
+ GroupGameStats(guList);
+ }
+
+ public Dictionary<GameUnit, GameUnitStatsNode> GameUnitNodes {
+ get {
+ return gameUnitNodes;
+ }
+ }
+
+ public GameUnitStatsNode GameNode {
+ get {
+ return gameNode;
+ }
+ }
+
+ void GroupGameStats (GameUnitsList guList)
+ {
+ List<GameUnitStatsNode> parents = new List<GameUnitStatsNode>();
+ parents.Add(gameNode);
+
+ foreach (GameUnit gu in guList) {
+ List<GameUnitStatsNode> nextParents = new List<GameUnitStatsNode>();
+ foreach (TimelineNode tn in gu) {
+ GameUnitStatsNode node = new GameUnitStatsNode(tn);
+ nextParents.Add(node);
+ FindParent(node, parents);
+ }
+ gameUnitNodes.Add(gu, new GameUnitStatsNode(game, nextParents));
+ parents = nextParents;
+ }
+ }
+
+ void FindParent (GameUnitStatsNode node, List<GameUnitStatsNode> parents) {
+ List <GameUnitStatsNode> candidates = parents.Where(p => Contained(node.Node, p.Node)).ToList();
+ if (candidates.Count != 1) {
+ Log.Warning(String.Format("Found {0} candidates for node {1}", candidates.Count, node));
+ }
+
+ foreach (GameUnitStatsNode parent in candidates)
+ parent.Add(node);
+ }
+
+ bool Contained (TimelineNode node, TimelineNode parent) {
+ if (node.Start > parent.Start && node.Stop < parent.Stop) {
+ return true;
+ } else if (node.Start > parent.Start && node.Stop > parent.Stop) {
+ return (node.Stop - parent.Stop) < node.Duration * MAX_DIFF;
+ } else if (node.Start < parent.Start && node.Stop < parent.Stop) {
+ return (parent.Start - node.Start) < node.Duration * MAX_DIFF;
+ } else {
+ return false;
+ }
+ }
+ }
+}
+
diff --git a/LongoMatch.Core/Stats/ProjectStats.cs b/LongoMatch.Core/Stats/ProjectStats.cs
index ef4d469..039378e 100644
--- a/LongoMatch.Core/Stats/ProjectStats.cs
+++ b/LongoMatch.Core/Stats/ProjectStats.cs
@@ -29,11 +29,11 @@ namespace LongoMatch.Stats
public class ProjectStats
{
List<CategoryStats> catStats;
+ GameUnitsStats guStats;
public ProjectStats (Project project)
{
- catStats = new List<CategoryStats>();
-
+ catStats = new List<CategoryStats>();
ProjectName = project.Description.Title;
Date = project.Description.MatchDate;
@@ -43,6 +43,7 @@ namespace LongoMatch.Stats
Season = project.Description.Season;
Results = String.Format("{0}-{1}", project.Description.LocalGoals, project.Description.VisitorGoals);
UpdateStats (project);
+ UpdateGameUnitsStats (project);
}
public string ProjectName {
@@ -75,17 +76,32 @@ namespace LongoMatch.Stats
set;
}
+ public string Results {
+ get;
+ set;
+ }
+
public List<CategoryStats> CategoriesStats {
get {
return catStats;
}
}
+ public GameUnitsStats GameUnitsStats {
+ get {
+ return guStats;
+ }
+ }
+
void CountPlaysInTeam (List<Play> plays, out int localTeamCount, out int visitorTeamCount) {
localTeamCount = plays.Where(p => p.Team == Team.LOCAL || p.Team == Team.BOTH).Count();
visitorTeamCount = plays.Where(p => p.Team == Team.VISITOR || p.Team == Team.BOTH).Count();
}
+ void UpdateGameUnitsStats (Project project) {
+ guStats = new GameUnitsStats(project.GameUnits, (int)project.Description.File.Length);
+ }
+
void UpdateStats (Project project) {
catStats.Clear();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]