public SnookerMatchScore Clone() { SnookerMatchScore obj = new SnookerMatchScore(); obj.ID = this.ID; obj.YourAthleteID = this.YourAthleteID; obj.YourName = this.YourName; obj.YourPicture = this.YourPicture; obj.OpponentAthleteID = this.OpponentAthleteID; obj.OpponentName = this.OpponentName; obj.OpponentPicture = this.OpponentPicture; obj.OpponentConfirmation = this.OpponentConfirmation; obj.IsUnfinished = this.IsUnfinished; obj.OpponentName = this.OpponentName; obj.VenueID = this.VenueID; obj.VenueName = this.VenueName; obj.Date = this.Date; obj.TableSize = this.TableSize; obj.MatchScoreA = this.MatchScoreA; obj.MatchScoreB = this.MatchScoreB; if (this.HasFrameScores) { obj.FrameScores = (from i in this.FrameScores select i.Clone()).ToList(); } if (this.YourBreaks != null) { obj.YourBreaks = (from i in this.YourBreaks select i.Clone()).ToList(); } if (this.OpponentBreaks != null) { obj.OpponentBreaks = (from i in this.OpponentBreaks select i.Clone()).ToList(); } return(obj); }
public static SnookerMatchScore FromScore(int athleteID, Score score) { SnookerMatchScore match = new SnookerMatchScore(); match.ID = score.ScoreID; match.YourAthleteID = score.AthleteAID; match.OpponentAthleteID = score.AthleteBID; match.VenueID = score.VenueID ?? 0; match.Date = score.Date; match.IsUnfinished = score.IsUnfinished; if (score.Type1 == null) { match.TableSize = SnookerTableSizeEnum.Unknown; } else { match.TableSize = (SnookerTableSizeEnum)score.Type1.Value; } match.MatchScoreA = score.PointsA; match.MatchScoreB = score.PointsB; match.OpponentConfirmation = (OpponentConfirmationEnum)score.AthleteBConfirmation; match.FrameScores = new List <SnookerFrameScore>(); for (int i = 1; i <= 10; ++i) { int a = score.InnerPointsA[i - 1]; int b = score.InnerPointsB[i - 1]; if (a > 0 || b > 0) { match.FrameScores.Add(new SnookerFrameScore() { A = a, B = b }); } } if (score.AthleteBID == athleteID) { // invert all match.YourAthleteID = score.AthleteBID; match.OpponentAthleteID = score.AthleteAID; match.MatchScoreA = score.PointsB; match.MatchScoreB = score.PointsA; foreach (var frame in match.FrameScores) { var a = frame.A; frame.A = frame.B; frame.B = a; } } // breaks if (score.ExtraData != null) { try { List <SnookerBreakDataCompressed> breaks = Newtonsoft.Json.JsonConvert.DeserializeObject <List <SnookerBreakDataCompressed> >(score.ExtraData); match.YourBreaks = new List <SnookerBreak>(); match.OpponentBreaks = new List <SnookerBreak>(); foreach (SnookerBreakDataCompressed compressed in breaks) { SnookerBreak snookerBreak = new SnookerBreak() { Date = compressed.Date, Points = compressed.Points, NumberOfBalls = compressed.Number, Balls = compressed.Balls.ToList(), FrameNumber = compressed.Frame, IsFoul = compressed.IsFoul }; if (compressed.AthleteID == match.OpponentAthleteID) { snookerBreak.AthleteID = match.OpponentAthleteID; snookerBreak.OpponentAthleteID = match.YourAthleteID; match.OpponentBreaks.Add(snookerBreak); } else { snookerBreak.AthleteID = match.YourAthleteID; snookerBreak.OpponentAthleteID = match.OpponentAthleteID; match.YourBreaks.Add(snookerBreak); } } } catch (Exception) { match.YourBreaks = null; match.OpponentBreaks = null; } } return(match); }
public SnookerFrameAnalysis Analyze(SnookerMatchScore match, int frameNumber) { SnookerFrameAnalysis analysis = new SnookerFrameAnalysis(); analysis.Status = SnookerFrameAnalysisEnum.Issues; analysis.Issue = ""; // all breaks List <SnookerBreak> breaks = match.GetBreaksForFrame(frameNumber).OrderBy(i => i.Date).ToList(); // do the frame scores total the breaks? if (match.FrameScores == null || frameNumber < match.FrameScores.Count) { analysis.Status = SnookerFrameAnalysisEnum.NotFullyTracked; analysis.Issue = "No frame scores"; return(analysis); } SnookerFrameScore frameScore = match.FrameScores[frameNumber - 1]; int pointsA = breaks.Where(i => i.AthleteID == match.YourAthleteID).Sum(i => i.Points); int pointsB = breaks.Where(i => i.AthleteID == match.OpponentAthleteID).Sum(i => i.Points); if (frameScore.A != pointsA || frameScore.B != pointsB) { analysis.Status = SnookerFrameAnalysisEnum.NotFullyTracked; analysis.Issue = "Frame score edited"; return(analysis); } // score difference int scoreDifference = System.Math.Abs(frameScore.A - frameScore.B); analysis.ScoreDifference = scoreDifference; /// go thru the breaks /// int numberOfRedsLeft = 15; int numberOfFouls = 0; int lastColoredPocketedBall = 1; foreach (var b in breaks) { int index = breaks.IndexOf(b) + 1; if (b.NumberOfBalls < 1) { analysis.Issue = "Empty break #" + index; return(analysis); } if (b.NumberOfBalls == 1 && b.Points >= 4 && b.Points <= 7) { numberOfFouls++; continue; } bool expectingColoredAfterRed = false; for (int i = 0; i < b.Balls.Count; ++i) { int ball = b.Balls[i]; if (numberOfRedsLeft > 0 || expectingColoredAfterRed) { // red, colored, red, colored if (expectingColoredAfterRed == true && ball == 1) { if (numberOfRedsLeft <= 0) { analysis.Issue = "Invalid break #" + index; return(analysis); } // several reds at the same time (happens when more than one red pocketed at the same time) numberOfRedsLeft--; continue; } if (expectingColoredAfterRed) { if (ball < 2 || ball > 7) { analysis.Issue = "Invalid break #" + index; return(analysis); } expectingColoredAfterRed = false; } else { if (ball != 1) { analysis.Issue = "Invalid break #" + index; return(analysis); } numberOfRedsLeft--; expectingColoredAfterRed = true; } } else { // last colored if (ball < 2 || ball > 7) { analysis.Issue = "Invalid break #" + index; return(analysis); } if (ball > lastColoredPocketedBall + 1 || ball == lastColoredPocketedBall) { numberOfFouls++; continue; } if (ball != lastColoredPocketedBall + 1) { analysis.Issue = "Invalid break #" + index; return(analysis); } lastColoredPocketedBall = ball; if (ball == 7) { bool ok = false; if (i == b.Balls.Count - 1) { ok = true; } if (i == b.Balls.Count - 2 && b.Balls[i + 1] == 7) { ok = true; } if (ok == false) { analysis.Issue = "Breaks after last ball potted"; return(analysis); } } } } } /// Calculate number of points left /// int numberOfLastColoredBallPointsLeft = 0; // maximum=2+3+4+5+6+7=27 for (int ball = 7; ball >= 2; --ball) { if (ball <= lastColoredPocketedBall) { break; } numberOfLastColoredBallPointsLeft += ball; } int numberOfPointsLeft = numberOfLastColoredBallPointsLeft; numberOfPointsLeft += numberOfRedsLeft * (1 + 7); /// Calculate snookers required /// int snookersRequired = 0; if (numberOfPointsLeft < scoreDifference) { int snookerPoints = 4; if (lastColoredPocketedBall > 4) { snookerPoints = lastColoredPocketedBall; } int extraPoints = scoreDifference - numberOfPointsLeft; snookersRequired = extraPoints / snookerPoints; if (extraPoints % snookerPoints > 0) { snookersRequired++; } } analysis.Status = SnookerFrameAnalysisEnum.FullyTracked; analysis.Issue = ""; analysis.NumberOfBreaks = breaks.Count - numberOfFouls; analysis.NumberOfFouls = numberOfFouls; analysis.NumberOfRedsLeft = numberOfRedsLeft; analysis.NumberOfPointsLeft = numberOfPointsLeft; analysis.SnookersRequired = snookersRequired; return(analysis); }