private void RemoveLastJamPenalties(Dictionary<int, List<Penalty>> playerPenaltyMap, Dictionary<int, List<BoxTime>> playerBoxTimeMap, List<PenaltyService> services) { var endGame = playerPenaltyMap.Values.SelectMany(p => p).Where(p => p.JamID == _lastJam.ID).ToList(); foreach (Penalty penalty in endGame) { if(playerBoxTimeMap.ContainsKey(penalty.PlayerID) && playerBoxTimeMap[penalty.PlayerID].Any() && playerBoxTimeMap[penalty.PlayerID].Last().JamID == _lastJam.ID) { continue; } Jam penaltyJam = _jams.First(j => j.ID == penalty.JamID); Player penaltyPlayer = _players[penalty.PlayerID]; Console.WriteLine(penaltyJam.ToString() + ": penalty by #" + penaltyPlayer.Number + " in last jam assumed to not have been served"); playerPenaltyMap[penalty.PlayerID].Remove(penalty); PenaltyService service = new PenaltyService(); service.Penalties.Add(penalty); services.Add(service); } }
private void HandleLeftoverPenalties(Dictionary<int, List<Penalty>> playerPenaltyMap, Dictionary<int, List<BoxTime>> playerBoxMap, Dictionary<int, bool> jamFullBoxMap, Dictionary<int, int> endJammerMap, List<PenaltyService> services) { var leftoverPenalties = playerPenaltyMap.Values.SelectMany(p => p).ToList(); var leftoverBoxes = playerBoxMap.Values.SelectMany(p => p).ToList(); // handle penalties with no time served while (leftoverPenalties.Count > 0) { Penalty penalty = leftoverPenalties[0]; Jam penaltyJam = _jams.First(j => j.ID == penalty.JamID); Player penaltyPlayer = _players[penalty.PlayerID]; bool wasEndJammer = endJammerMap.ContainsKey(penaltyJam.ID) && endJammerMap[penaltyJam.ID] == penaltyPlayer.ID; PenaltyService service = new PenaltyService(); service.Penalties.Add(penalty); // if no time was served, it's conceivable the penalty didn't get served until later on // TODO: confirm jammer penalty+service matching var matchingBoxes = leftoverBoxes .Where(bt => (bt.JamID > penalty.JamID && bt.IsJammer == wasEndJammer) || (bt.JamID == penalty.JamID && bt.PlayerID == penalty.PlayerID)) .OrderBy(bt => bt.JamID); if (matchingBoxes.Any()) { BoxTime bestBox = matchingBoxes.First(); Jam boxTimeJam = _jams.First(j => j.ID == bestBox.JamID); Player boxTimePlayer = _players[bestBox.PlayerID]; int nextJamID = GetNextJamID(penaltyJam.ID); if (boxTimeJam.ID - penaltyJam.ID > 1 && (!jamFullBoxMap.ContainsKey(nextJamID) || !jamFullBoxMap[nextJamID])) { string errorString = string.Format("{0}: penalty by {1} {2} does not appear correctly served.", penaltyJam.ToString(), penaltyPlayer.Number, penaltyPlayer.Name); Console.WriteLine(errorString); throw new InvalidDataException(errorString); } Console.WriteLine(string.Format("{0}: penalty by {1} {2} served by {3} {4}", penaltyJam.ToString(), penaltyPlayer.Number, penaltyPlayer.Name, boxTimePlayer.Number, boxTimePlayer.Name)); service.BoxTimes.Add(bestBox); leftoverBoxes.Remove(bestBox); playerBoxMap[bestBox.PlayerID].Remove(bestBox); leftoverPenalties.Remove(penalty); playerPenaltyMap[penalty.PlayerID].Remove(penalty); // see if this penalty has friends var hangersOn = leftoverPenalties.Where(p => p.JamID == penalty.JamID && p.PlayerID == penalty.PlayerID && p.PenaltyNumber != penalty.PenaltyNumber).ToList(); foreach (Penalty extra in hangersOn) { service.Penalties.Add(extra); leftoverPenalties.Remove(extra); playerPenaltyMap[extra.PlayerID].Remove(extra); } // get the ending jam of the service while (bestBox.EndedJamInBox && bestBox.JamID < _lastJam.ID) { BoxTime previousBox = bestBox; bestBox = leftoverBoxes.Where(bt => bt.StartedJamInBox == true && bt.JamID == bestBox.JamID + 1 && bt.PlayerID == bestBox.PlayerID).FirstOrDefault(); if (bestBox == null) { boxTimeJam = _jams.First(j => j.ID == previousBox.JamID); throw new InvalidDataException(boxTimeJam.ToString() + ": box time by #" + boxTimePlayer.Number + " does not appear correctly finished."); } service.BoxTimes.Add(bestBox); leftoverBoxes.Remove(bestBox); playerBoxMap[bestBox.PlayerID].Remove(bestBox); } services.Add(service); } else { Jam jam = _jams.First(j => j.ID == penalty.JamID); Player player = _players[penalty.PlayerID]; Console.WriteLine(string.Format("{0}: Unhandled Penalty for {1} {2}.", jam.ToString(), player.Number, player.Name)); throw new InvalidDataException(string.Format("{0}: Unhandled Penalty for {1} {2}.", jam.ToString(), player.Number, player.Name)); } } }
private void HandleSpecialCases(Dictionary<int, List<Penalty>> playerPenaltyMap, Dictionary<int, List<BoxTime>> playerBoxTimeMap, List<PenaltyService> services) { Dictionary<char?, PenaltyService> specialServiceMap = new Dictionary<char?, PenaltyService>(); var matchedPenalties = playerPenaltyMap.Values.SelectMany(p => p).Where(p => p.MatchingKey != null).ToList(); foreach(Penalty specialPenalty in matchedPenalties) { if (!specialServiceMap.ContainsKey(specialPenalty.MatchingKey)) { var matchingBoxes = playerBoxTimeMap.Values.SelectMany(bt => bt).Where(bt => bt.MatchingKey == specialPenalty.MatchingKey).ToList(); if (!matchingBoxes.Any()) { throw new InvalidDataException("No box times match the special case character " + specialPenalty.MatchingKey); } PenaltyService service = new PenaltyService(); // find all boxes that match this special character foreach (BoxTime bt in matchingBoxes) { service.BoxTimes.Add(bt); playerBoxTimeMap[bt.PlayerID].Remove(bt); } specialServiceMap[specialPenalty.MatchingKey] = service; services.Add(service); } specialServiceMap[specialPenalty.MatchingKey].Penalties.Add(specialPenalty); playerPenaltyMap[specialPenalty.PlayerID].Remove(specialPenalty); } }
private List<PenaltyService> ConvertBoxTimeList(List<BoxTime> playerBoxTimes) { List<PenaltyService> penaltyService = new List<PenaltyService>(); int boxTimeIndex = 0; while(boxTimeIndex < playerBoxTimes.Count) { PenaltyService service = new PenaltyService(); BoxTime lastBoxTime = playerBoxTimes[boxTimeIndex]; service.BoxTimes.Add(lastBoxTime); if(lastBoxTime.MatchingKey != null) { service.ServiceKey = lastBoxTime.MatchingKey; } boxTimeIndex++; while (lastBoxTime.EndedJamInBox && boxTimeIndex < playerBoxTimes.Count) { int nextJamID = GetNextJamID(lastBoxTime.JamID); BoxTime nextBoxTime = playerBoxTimes[boxTimeIndex]; if(nextBoxTime.JamID == nextJamID && (nextBoxTime.StartedJamInBox == null || nextBoxTime.StartedJamInBox == true)) { nextBoxTime.StartedJamInBox = true; service.BoxTimes.Add(nextBoxTime); lastBoxTime = nextBoxTime; boxTimeIndex++; } else { Jam jam = _jams.First(j => j.ID == lastBoxTime.JamID); Player player = _players[lastBoxTime.PlayerID]; Console.WriteLine(string.Format("{0}: No box time continuation for {1} {2}", jam.ToString(), player.Number, player.Name)); break; } } penaltyService.Add(service); } return penaltyService; }