public bool HoleIsPushed(int hole) { return(Shots.Any(s => s.Hole.Id == hole && s.ShotType.Id == ShotTypePush)); }
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); }
public int GetCurrentHole() { _currentHole = 1; if (Shots.Any()) { _currentHole = Shots.Max(s => s.Hole.Id); var holeShots = Shots.Where(s => s.Hole.Id == _currentHole.Value).ToList(); if (_currentHole.Value == 1) { // If we are on the first hole, there's no way of knowing when to go to the next hole // because we don't know how many players are going (unless it's been pushed on 1) if (holeShots.Count(s => s.Attempts == 1 && s.ShotMade) > 1) { _currentHole += 1; return(_currentHole.Value); } else { return(_currentHole.Value); } } else { // If the hole was pushed on 1, go to the next hole if (holeShots.Count(s => s.Attempts == 1 && s.ShotMade) > 1) { _currentHole++; return(_currentHole.Value); } var totalPlayers = GetCurrentActivePlayers(ActivePlayers, includeOvertime: false).Count(); // If everyone has gone, go to the next hole if (holeShots.Count() == totalPlayers) { _currentHole++; } // TODO: This needs to change to a MAX function for hole number when the new hole/overtime logic is added if (_currentHole.Value >= 10) { var newHoleShots = Shots.Where(s => s.Hole.Id == _currentHole.Value).ToList(); if (newHoleShots.Count(s => s.Attempts == 1 && s.ShotMade) > 1 || HoleIsPushed(_currentHole.Value)) { // Two people have made the shot in 1, move on to the next _currentHole++; return(_currentHole.Value); } else { // NOTE: Anything going off of x.Player.Shots is runs a shitload of queries... avoid var playersWhoCanWin = GetPlayersWhoCanWin(_currentHole.Value).Where(g => Shots.Count(s => s.Hole.Id == _currentHole.Value && !s.ShotMade && s.Player.Id == g.Player.Id) == 0); if (playersWhoCanWin.Count() == 0) { _currentHole++; return(_currentHole.Value); } else { return(_currentHole.Value); } } } } } return(_currentHole.Value); }