public bool IsPenalty(Player player, Position position, out IncorrectPosition penalty) { if (player.PositionPrimary == position) { penalty = null; return(false); } bool usedSecondary = player.PositionSecondary == position; EffectiveGrade effectiveGrade = new EffectiveGrade(player, position); double score; if (usedSecondary) { score = weights.SecondaryPosition.Score; } else if (Tools.PositionCouldBeSecondary(position, player)) { score = weights.IncorrectPosition.Score; } else { score = weights.IncorrectPosition.Score * 3; } if (player.PositionPrimary == Position.Lead && player.GradePrimary != Grade.G1) { score += weights.GoodLeadsMoveUp.Score; } else if (player.PositionPrimary == Position.Skip && player.GradePrimary == Grade.G1) { score += weights.GoodSkipsGetSkip.Score; } if (!incorrectPositions.TryGetValue(player, out HistoryOfPenalty historical)) { historical = new HistoryOfPenalty(); // todo adjust history depending on severity } penalty = new IncorrectPosition { player = player, givenPosition = position, wantedPosition = player.PositionPrimary, grade = effectiveGrade.grade, score = score, usedSecondary = usedSecondary, historical = historical, }; return(true); }
public static void Output(string filename, IList <Player> players, IList <Day> history, Weights weights) { if (!Directory.Exists(Path.GetDirectoryName(filename))) { Directory.CreateDirectory(Path.GetDirectoryName(filename)); } using StreamWriter streamWriter = new StreamWriter(filename); streamWriter.Write(JsonConvert.SerializeObject(new Dict() { { "players", players.Select(WritePlayer) }, { "history", history.Select(WriteDay) }, { "weights", WriteWeights(weights) }, })); Dict WritePlayer(Player player) => new Dict { { "Name", player.Name }, { "ID", player.ID }, { "PositionPrimary", player.PositionPrimary }, { "PositionSecondary", player.PositionSecondary }, { "GradePrimary", player.GradePrimary }, { "GradeSecondary", player.GradeSecondary }, { "PreferredTeamSizes", player.PreferredTeamSizes }, { "TagNumber", player.TagNumber }, }; Dict WriteDay(Day day) => new Dict { { "date", day.date }, { "matches", day.matches.Select(WriteMatch) }, }; Dict WriteMatch(Match match) => new Dict { { "Rink", match.rink }, { "isFixed", match.isFixed }, { "dontModify", match.dontModify }, { "Team1", TeamAsString(match.Team1) }, { "Team2", TeamAsString(match.Team2) }, { "penalties", match.penalties.Select(WritePenalty) } }; IEnumerable <T> relevantToTeam <T>(Team team, IList <T> list) { for (int position = 0; position < Team.MaxSize; position++) { if (team.PositionShouldBeFilled((Position)position)) { yield return(list[position]); } } } string TeamAsString(Team team) => string.Join(",", relevantToTeam(team, team.players).Select(ConvertPlayer)); string ConvertPlayer(Player player) => player?.ID.ToString() ?? "_"; Dict WritePenalty(Penalty penalty) => penalty switch { PairAlreadyPlayedInTeam p => WritePenaltyPAIRALREADYPLAYEDINTEAM(p), PairAlreadyPlayedAgainstEachOther p => WritePenaltyPAIRALREADYPLAYEDAGAINSTEACHOTHER(p), IncorrectPosition p => WritePenaltyINCORRECTPOSITION(p), WrongTeamSize p => WritePenaltyWRONGTEAMSIZE(p), UnbalancedPlayers p => WritePenaltyUNBALANCEDPLAYERS(p), UnbalancedTeams p => WritePenaltyUNBALANCEDTEAMS(p), _ => throw new ArgumentException("Unknown penalty") }; Dict WritePenaltyPAIRALREADYPLAYEDINTEAM(PairAlreadyPlayedInTeam penalty) => new Dict { { "type", "PAIRALREADYPLAYEDINTEAM" }, { "historical.mostRecentGameIndex", penalty.historical.mostRecentGameIndex }, { "historical.numberOfOccurences", penalty.historical.numberOfOccurences }, { "historical.score", penalty.historical.score }, { "player1", ConvertPlayer(penalty.player1) }, { "player2", ConvertPlayer(penalty.player2) }, { "score", penalty.score }, }; Dict WritePenaltyPAIRALREADYPLAYEDAGAINSTEACHOTHER(PairAlreadyPlayedAgainstEachOther penalty) => new Dict { { "type", "PAIRALREADYPLAYEDAGAINSTEACHOTHER" }, { "historical.mostRecentGameIndex", penalty.historical.mostRecentGameIndex }, { "historical.numberOfOccurences", penalty.historical.numberOfOccurences }, { "historical.score", penalty.historical.score }, { "player1", ConvertPlayer(penalty.player1) }, { "player2", ConvertPlayer(penalty.player2) }, { "score", penalty.score }, }; Dict WritePenaltyINCORRECTPOSITION(IncorrectPosition penalty) => new Dict { { "type", "INCORRECTPOSITION" }, { "historical.mostRecentGameIndex", penalty.historical.mostRecentGameIndex }, { "historical.numberOfOccurences", penalty.historical.numberOfOccurences }, { "historical.score", penalty.historical.score }, { "player", ConvertPlayer(penalty.player) }, { "givenPosition", penalty.givenPosition }, { "wantedPosition", penalty.wantedPosition }, { "usedSecondary", penalty.usedSecondary }, { "grade", penalty.grade }, }; Dict WritePenaltyWRONGTEAMSIZE(WrongTeamSize penalty) => new Dict { { "type", "WRONGTEAMSIZE" }, { "historical.mostRecentGameIndex", penalty.historical.mostRecentGameIndex }, { "historical.numberOfOccurences", penalty.historical.numberOfOccurences }, { "historical.score", penalty.historical.score }, { "player", ConvertPlayer(penalty.player) }, { "score", penalty.score }, { "givenSize", penalty.givenSize }, { "wantedSize", penalty.wantedSize }, }; Dict WritePenaltyUNBALANCEDPLAYERS(UnbalancedPlayers penalty) => new Dict { { "type", "UNBALANCEDPLAYERS" }, { "historical.mostRecentGameIndex", penalty.historical.mostRecentGameIndex }, { "historical.numberOfOccurences", penalty.historical.numberOfOccurences }, { "historical.score", penalty.historical.score }, { "player1", ConvertPlayer(penalty.player1) }, { "player2", ConvertPlayer(penalty.player2) }, { "grade1", WriteEffectiveGrade(penalty.grade1) }, { "grade2", WriteEffectiveGrade(penalty.grade2) }, { "score", penalty.score }, }; Dict WritePenaltyUNBALANCEDTEAMS(UnbalancedTeams penalty) => new Dict { { "type", "UNBALANCEDTEAMS" }, { "score", penalty.score }, { "grade1", relevantToTeam(penalty.match.Team1, penalty.team1Grades).Select(WriteEffectiveGrade) }, { "grade2", relevantToTeam(penalty.match.Team2, penalty.team2Grades).Select(WriteEffectiveGrade) }, }; Dict WriteEffectiveGrade(EffectiveGrade effectiveGrade) => new Dict { { "grade", effectiveGrade.grade }, { "positionIsPrimary", effectiveGrade.positionIsPrimary }, { "positionIsSecondary", effectiveGrade.positionIsSecondary }, }; Dict WriteWeights(Weights weights) => new Dict { { "IncorrectPosition", WriteWeight(weights.IncorrectPosition) }, { "IncorrectTeamSize", WriteWeight(weights.IncorrectTeamSize) }, { "PairPlayedTogetherAgainstEachOther", WriteWeight(weights.PairPlayedTogetherAgainstEachOther) }, { "PairPlayedTogetherInTeam", WriteWeight(weights.PairPlayedTogetherInTeam) }, { "SecondaryPosition", WriteWeight(weights.SecondaryPosition) }, { "UnbalancedPlayers", WriteWeight(weights.UnbalancedPlayers) }, { "UnbalancedTeams", WriteWeight(weights.UnbalancedTeams) }, { "GoodSkipsGetSkip", WriteWeight(weights.GoodSkipsGetSkip) }, { "GoodLeadsMoveUp", WriteWeight(weights.GoodLeadsMoveUp) }, }; Dict WriteWeight(Weight weight) => new Dict { { "Score", weight.Score }, { "Multiplier", weight.Multiplier }, }; }