private Player GetCurrentPlayer()
{
var playerResult = new Player();
int currentHole = GetCurrentHole();
if (Shots.Any())
{
var activePlayers = ActivePlayers;
var playersDescending = GetCurrentActivePlayers(activePlayers, includeOvertime: false);
var duplicatePlayers = Shots.GroupBy(s => s.Player.Id).Where(p => p.Count() > 1);
// Check to see if we've had any duplicate players yet (if so, that means we can determine the order)
if (duplicatePlayers.Any())
{
// If we are on the last hole or in overtime, the order could change because not everyone can win
if (currentHole >= 10)
{
var playersWhoCanWin = GetPlayersWhoCanWin(currentHole);
if (!playersWhoCanWin.Any() || playersWhoCanWin.Count() >= playersDescending.Count())
{
// If all of the players can win, we will go in normal order
var lastPlayerToShoot = Shots.Where(s => s.Game.Id == Game.Id).OrderByDescending(s => s.Id).Select(s => s.Player).First();
var playerList = playersDescending.Reverse().ToList();
int index = playerList.IndexOf(lastPlayerToShoot);
return playerList[index == -1 ? 0 : (index + 1) % (playerList.Count)];
}
else
{
// If only some of the players can win, we will go in descending order by points
var playersWhoCanStillWin = new List<LeaderboardViewModel>();
foreach (var player in playersWhoCanWin)
{
var playerCurrentHoleShots = Shots.Where(s => s.Player.Id == player.Player.Id && s.Game.Id == Game.Id && s.Hole.Id == currentHole);
if (!playerCurrentHoleShots.Any())
{
playersWhoCanStillWin.Add(player);
}
}
var playersWhoCannotWin = new List<Player>();
if (playersWhoCanStillWin.Count == 0)
{
if (HoleIsPushed(currentHole))
{
return playersWhoCanStillWin.First().Player;
}
// This means that one of the players who could win made a shot, so all of the people
// that cannot win need to take a shot to push them
foreach (var player in playersDescending)
{
if (!Shots.Any(s => s.Player.Id == player.Id && s.Hole.Id == currentHole))
{
if (!playersWhoCanWin.Any(l => l.Player.Id == player.Id))
{
playersWhoCannotWin.Add(player);
}
}
}
// TODO: Here we need to figure out the order that these players who can push
// the hole need to go in. My thought is that the players with the least amount of
// pushes for the current period (in our case month) get to go first.
if (playersWhoCannotWin.Any())
{
return playersWhoCannotWin.Last();
}
else
{
return playersDescending.Last();
}
}
else
{
return playersWhoCanStillWin.OrderByDescending(l => l.Points).First().Player;
}
}
}
return playersDescending.Last();
}
else
{
// TODO: My thought for initial player order is that the people with the lowest shooting percentage
// get to go first, and once one of them makes it, the players with the lowest pushes get to go second
// If we can't determine the order, just get the next player who has not gone already
foreach (var player in _allPlayers)
{
if (!activePlayers.Any(p => p.Id == player.Id))
{
return player;
}
}
}
}
return playerResult;
}