private IEnumerable<LeaderboardViewModel> GetPlayersWhoCanWin(int currentHole)
{
if (_playersWhoCanWin == null)
{
int currentPointsAvailable = GetPointsAvailable(currentHole);
var leaderboard = Leaderboard.OrderByDescending(l => l.Points);
var leader = leaderboard.First();
// This is the leader's points not counting any temporary points scored on the current hole
var leaderPoints = Shots.Where(s => s.Player.Id == leader.Player.Id && s.Hole.Id < currentHole).Sum(s => s.Points);
if (leaderboard.Count(l => l.Points > leaderPoints) > 1)
{
var leaderAtBeginningOfHole = leaderboard.Where(l => l.Player.Id != leader.Player.Id).OrderByDescending(l => l.Points);
leaderPoints = leaderAtBeginningOfHole.First().Points;
}
var playersWhoCanWin = new List<LeaderboardViewModel>();
foreach (var player in leaderboard)
{
// If the player has already gone on this hole and made the shot then we need to
// subtract those points for the next calculation
var newPlayerCurrentHoleShot = Shots.Where(s => s.Player.Id == player.Player.Id && s.Hole.Id == currentHole && s.Points > 0);
int playerCurrentHolePoints = newPlayerCurrentHoleShot.Any() ? newPlayerCurrentHoleShot.First().Points : 0;
// If the player can at least tie the leader, then he gets to take all shots
if (((player.Points - playerCurrentHolePoints) + currentPointsAvailable) >= leaderPoints)
{
playersWhoCanWin.Add(player);
}
}
_playersWhoCanWin = playersWhoCanWin;
}
return _playersWhoCanWin;
}