コード例 #1
0
 public bool HoleIsPushed(int hole)
 {
     return(Shots.Any(s => s.Hole.Id == hole && s.ShotType.Id == ShotTypePush));
 }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }