diff --git a/KingsAndQueensHat/KingsAndQueensHat.csproj b/KingsAndQueensHat/KingsAndQueensHat.csproj
index 1d87ee7..d4b7928 100644
--- a/KingsAndQueensHat/KingsAndQueensHat.csproj
+++ b/KingsAndQueensHat/KingsAndQueensHat.csproj
@@ -60,6 +60,7 @@
+
diff --git a/KingsAndQueensHat/Model/Team.cs b/KingsAndQueensHat/Model/Team.cs
index 53d6af8..09da48f 100644
--- a/KingsAndQueensHat/Model/Team.cs
+++ b/KingsAndQueensHat/Model/Team.cs
@@ -85,6 +85,15 @@ public int TotalSkill
get { return Players.Sum(p => p.SkillValue); }
}
+ [XmlIgnore]
+ public Dictionary GenderSkills
+ {
+ get
+ {
+ return Players.GroupBy(p => p.Gender).Select(g => new {g.Key, Skill = g.Sum(p => p.SkillValue)}).ToDictionary(x => x.Key, x => x.Skill);
+ }
+ }
+
[XmlIgnore]
public int PlayerCount
{
diff --git a/KingsAndQueensHat/Model/Tournament.cs b/KingsAndQueensHat/Model/Tournament.cs
index 1b2d80c..ccd0790 100644
--- a/KingsAndQueensHat/Model/Tournament.cs
+++ b/KingsAndQueensHat/Model/Tournament.cs
@@ -154,7 +154,8 @@ public async Task CreateNewRound(int teamCount, CancellationToken cancel)
var penalty1 = new UnevenSkillPenalty();
var penalty3 = new TooManyWinnersPenalty(PlayerProvider);
var penalty4 = new RangeOfSkillsPenalty();
- var penalties = new IPenalty[] { penalty1, _playerPairings, penalty3, penalty4 };
+ var penalty5 = new UnevenGenderSkillPenalty();
+ var penalties = new IPenalty[] { penalty1, _playerPairings, penalty3, penalty4, penalty5 };
var teams = await teamCreator.CreateApproximatelyOptimalTeams(penalties, PlayerProvider, numTeamGens, teamCount, cancel);
diff --git a/KingsAndQueensHat/TeamGeneration/UnevenGenderSkillPenalty.cs b/KingsAndQueensHat/TeamGeneration/UnevenGenderSkillPenalty.cs
new file mode 100644
index 0000000..978bdfb
--- /dev/null
+++ b/KingsAndQueensHat/TeamGeneration/UnevenGenderSkillPenalty.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using KingsAndQueensHat.Model;
+
+namespace KingsAndQueensHat.TeamGeneration
+{
+ ///
+ /// Penalise team allocations that leave some teams with a particular dominant gender
+ /// , while others do not
+ ///
+ public class UnevenGenderSkillPenalty : IPenalty
+ {
+ public double ScorePenalty(List teams)
+ {
+ var scores = teams.Select(team => team.GenderSkills).ToList();
+ int result = 0;
+ foreach (var gender in new[] { Gender.Male, Gender.Female })
+ {
+ var total = scores.Sum(s => s[gender]);
+ var teamCount = teams.Count;
+ var expectedTeamGenderSkill = total / teamCount;
+
+ // Sum the deviations from the expected team skill
+ result += scores.Sum(s => Math.Abs(s[gender] - expectedTeamGenderSkill));
+ }
+ return result;
+ }
+
+ public double Weighting { get { return 1.0; } }
+ }
+}