private List <CheckViewModel> HandleTwoDartFinishes(int score) { var checks = new List <CheckViewModel>(); foreach (var field in GetRelevantFields()) { CheckViewModel check; var prop = 0.0; var oneDartFinish = score == field.Value && field.Type == FieldEnum.Double; if (oneDartFinish) { check = HandleLastDart(score).Single(); prop = check.Check.Propability; } else { check = HandleLastDart(score - field.Value)?.FirstOrDefault(); if (check == null) { continue; } prop = check.Check.Propability * CheckSimulator.GetSuccessRate(field, _config.My, _config.Sigma); } var subChecks = new List <Check>(); var dict = CheckSimulator.GetNeighbors(field, _config.My, _config.Sigma); foreach (var neighbor in dict.Keys) { if (score - neighbor.Value == 0 && (neighbor.Type == FieldEnum.Double || neighbor.Type == FieldEnum.DoubleBull)) { var randomCheck = new CheckViewModel(neighbor, null, null, dict[neighbor], dict[neighbor]); prop += dict[neighbor]; subChecks.Add(randomCheck.Check); continue; } var subCheck = HandleLastDart(score - neighbor.Value) ?.FirstOrDefault(); if (subCheck == null) { continue; } subCheck.Check.AufCheckDart = neighbor; subCheck.Check.Propability = subCheck.Check.Propability * dict[neighbor]; prop += subCheck.Check.Propability; subChecks.Add(subCheck.Check); } var newCheck = new CheckViewModel(field, check.Check.CheckDart, null, prop, check.Check.Propability * CheckSimulator.GetSuccessRate(field, _config.My, _config.Sigma), subChecks); if (oneDartFinish) { newCheck = new CheckViewModel(field, null, null, prop, prop, subChecks); } checks.Add(newCheck); } return(checks.OrderByDescending(x => x.Check.Propability).ToList()); }
public List <CheckViewModel> CalculateChecks(int score, int leftDarts, BackgroundWorker worker, bool clearCache = false) { if (!IsAFinish(score, leftDarts)) { return(null); } if (leftDarts == 1) { return(HandleLastDart(score)); } if (leftDarts == 2) { return(HandleTwoDartFinishes(score)); } var checks = new List <CheckViewModel>(); var list = GetRelevantFields(); var idx = 0; Parallel.ForEach(list, (field) => { CheckSimulator.GetSuccessRate(field, _config.My, _config.Sigma); idx++; worker?.ReportProgress(idx * 100 / list.Count); }); for (var index = 0; index < list.Count; index++) { worker?.ReportProgress(index * 100 / list.Count); var field = list[index]; if (field.Value > score) { continue; } var oneDartFinish = score == field.Value && field.Type == FieldEnum.Double; List <CheckViewModel> currentChecks; var prop = 0.0; if (oneDartFinish) { currentChecks = CalculateChecks(score, leftDarts - 2, worker); } else { currentChecks = CalculateChecks(score - field.Value, leftDarts - 1, worker); if (currentChecks == null) { continue; } } var neighborSubChecks = new List <Check>(); var dict = CheckSimulator.GetNeighbors(field, _config.My, _config.Sigma); foreach (var neighbor in dict.Keys) { if (score - neighbor.Value == 0 && (neighbor.Type == FieldEnum.Double || neighbor.Type == FieldEnum.DoubleBull)) { var randomCheck = new CheckViewModel(neighbor, null, null, dict[neighbor], dict[neighbor]); prop += dict[neighbor]; neighborSubChecks.Add(randomCheck.Check); continue; } var subCheck = CalculateChecks(score - neighbor.Value, leftDarts - 1, worker) ?.FirstOrDefault(); if (subCheck == null) { continue; } if (subCheck.Check.AufCheckDart == null) { subCheck.Check.AufCheckDart = neighbor; } else { subCheck.Check.ScoreDart = neighbor; } subCheck.Check.Propability = subCheck.Check.Propability * dict[neighbor]; prop += subCheck.Check.Propability; neighborSubChecks.Add(subCheck.Check); subCheck.Check.SubChecks.ForEach(x => { if (x.AufCheckDart == null) { x.AufCheckDart = neighbor; } else { x.ScoreDart = neighbor; } x.Propability = x.Propability * dict[neighbor]; }); //neighborSubChecks.AddRange(subCheck.Check.SubChecks); } foreach (var currentCheck in currentChecks) { var propx = prop; var subChecks = new List <Check>(neighborSubChecks); if (!oneDartFinish) { currentCheck.Check.SubChecks.ForEach(x => { x.ScoreDart = field; x.Propability = x.Propability * CheckSimulator.GetSuccessRate(field, _config.My, _config.Sigma); propx += x.Propability; }); subChecks.AddRange(currentCheck.Check.SubChecks); } if (oneDartFinish) { var exactProp = CheckSimulator.GetSuccessRate(field, _config.My, _config.Sigma); var propa = exactProp + propx; checks.Add(new CheckViewModel(field, null, null, propa, exactProp, subChecks)); } else if (currentCheck.Check.AufCheckDart != null) { var exactProp = CheckSimulator.GetSuccessRate(field, _config.My, _config.Sigma) * CheckSimulator.GetSuccessRate(currentCheck.Check.AufCheckDart, _config.My, _config.Sigma) * CheckSimulator.GetSuccessRate(currentCheck.Check.CheckDart, _config.My, _config.Sigma); var propa = exactProp + propx; checks.Add(new CheckViewModel(field, currentCheck.Check.AufCheckDart, currentCheck.Check.CheckDart, propa, exactProp, subChecks)); } else { var exactProp = CheckSimulator.GetSuccessRate(field, _config.My, _config.Sigma) * CheckSimulator.GetSuccessRate(currentCheck.Check.CheckDart, _config.My, _config.Sigma); var propa = exactProp + propx; checks.Add(new CheckViewModel(field, currentCheck.Check.CheckDart, null, propa, exactProp, subChecks)); } } } return(checks.OrderByDescending(x => x.Check.Propability).ToList()); }