namespace Bullseye { /// /// Class encompassing the game /// public class BullseyeGame { private readonly List _players; // define a constant for the winning score so that it is // easy to change again in the future private const int WinningScore = 200; public BullseyeGame() { // create the initial list of players; list is empty, but // the setup of the game will add items to this list _players = new List(); } public void Run() { PrintIntroduction(); SetupGame(); PlayGame(); PrintResults(); } private void SetupGame() { // First, allow the user to enter how many players are going // to play. This could be weird if the user enters negative // numbers, words, or too many players, so there are some // extra checks on the input to make sure the user didn't do // anything too crazy. Loop until the user enters valid input. bool validPlayerCount; int playerCount; do { Console.WriteLine(); Console.Write("HOW MANY PLAYERS? "); string? input = Console.ReadLine(); // assume the user has entered something incorrect - the // next steps will validate the input validPlayerCount = false; if (Int32.TryParse(input, out playerCount)) { if (playerCount > 0 && playerCount <= 20) { validPlayerCount = true; } else { Console.WriteLine("YOU MUST ENTER A NUMBER BETWEEN 1 AND 20!"); } } else { Console.WriteLine("YOU MUST ENTER A NUMBER"); } } while (!validPlayerCount); // Next, allow the user to enter names for the players; as each // name is entered, create a Player object to track the name // and their score, and save the object to the list in this class // so the rest of the game has access to the set of players for (int i = 0; i < playerCount; i++) { string? playerName = String.Empty; do { Console.Write($"NAME OF PLAYER #{i+1}? "); playerName = Console.ReadLine(); // names can be any sort of text, so allow whatever the user // enters as long as it isn't a blank space } while (String.IsNullOrWhiteSpace(playerName)); _players.Add(new Player(playerName)); } } private void PlayGame() { Random random = new Random(DateTime.Now.Millisecond); int round = 0; bool isOver = false; do { // starting a new round, increment the counter round++; Console.WriteLine($"ROUND {round}"); Console.WriteLine("--------------"); foreach (Player player in _players) { // ask the user how they want to throw Console.Write($"{player.Name.ToUpper()}'S THROW: "); string? input = Console.ReadLine(); // based on the input, figure out the probabilities int[] probabilities; switch (input) { case "1": { probabilities = new int[] { 65, 55, 50, 50 }; break; } case "2": { probabilities = new int[] { 99, 77, 43, 1 }; break; } case "3": { probabilities = new int[] { 95, 75, 45, 5 }; break; } default: { // in case the user types something bad, pretend it's // as if they tripped over themselves while throwing // the dart - they'll either hit a bullseye or completely // miss probabilities = new int[] { 95, 95, 95, 95 }; Console.Write("TRIP! "); break; } } // Next() returns a number in the range: min <= num < max, so specify 101 // as the maximum so that 100 is a number that could be returned int chance = random.Next(0, 101); if (chance > probabilities[0]) { player.Score += 40; Console.WriteLine("BULLSEYE!! 40 POINTS!"); } else if (chance > probabilities[1]) { player.Score += 30; Console.WriteLine("30-POINT ZONE!"); } else if (chance > probabilities[2]) { player.Score += 20; Console.WriteLine("20-POINT ZONE"); } else if (chance > probabilities[3]) { player.Score += 10; Console.WriteLine("WHEW! 10 POINTS."); } else { // missed it Console.WriteLine("MISSED THE TARGET! TOO BAD."); } // check to see if the player has won - if they have, then // break out of the loops if (player.Score > WinningScore) { Console.WriteLine(); Console.WriteLine("WE HAVE A WINNER!!"); Console.WriteLine($"{player.Name.ToUpper()} SCORED {player.Score} POINTS."); Console.WriteLine(); isOver = true; // out of the do/while round loop break; // out of the foreach (player) loop } Console.WriteLine(); } } while (!isOver); } private void PrintResults() { // For bragging rights, print out all the scores, but sort them // by who had the highest score var sorted = _players.OrderByDescending(p => p.Score); // padding is used to get things to line up nicely - the results // should look something like: // PLAYER SCORE // Bravo 210 // Charlie 15 // Alpha 1 Console.WriteLine("PLAYER SCORE"); foreach (var player in sorted) { Console.WriteLine($"{player.Name.PadRight(12)} {player.Score.ToString().PadLeft(5)}"); } Console.WriteLine(); Console.WriteLine("THANKS FOR THE GAME."); } private void PrintIntroduction() { Console.WriteLine(Title); Console.WriteLine(); Console.WriteLine(Introduction); Console.WriteLine(); Console.WriteLine(Operations); } private const string Title = @" BULLSEYE CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"; private const string Introduction = @" IN THIS GAME, UP TO 20 PLAYERS THROW DARTS AT A TARGET WITH 10, 20, 30, AND 40 POINT ZONES. THE OBJECTIVE IS TO GET 200 POINTS."; private const string Operations = @" THROW DESCRIPTION PROBABLE SCORE 1 FAST OVERARM BULLSEYE OR COMPLETE MISS 2 CONTROLLED OVERARM 10, 20, OR 30 POINTS 3 UNDERARM ANYTHING"; } }