|
| 1 | +namespace Bullseye |
| 2 | +{ |
| 3 | + /// <summary> |
| 4 | + /// Class encompassing the game |
| 5 | + /// </summary> |
| 6 | + public class BullseyeGame |
| 7 | + { |
| 8 | + private readonly List<Player> _players; |
| 9 | + |
| 10 | + // define a constant for the winning score so that it is |
| 11 | + // easy to change again in the future |
| 12 | + private const int WinningScore = 200; |
| 13 | + |
| 14 | + public BullseyeGame() |
| 15 | + { |
| 16 | + // create the initial list of players; list is empty, but |
| 17 | + // the setup of the game will add items to this list |
| 18 | + _players = new List<Player>(); |
| 19 | + } |
| 20 | + |
| 21 | + public void Run() |
| 22 | + { |
| 23 | + PrintIntroduction(); |
| 24 | + |
| 25 | + SetupGame(); |
| 26 | + |
| 27 | + PlayGame(); |
| 28 | + |
| 29 | + PrintResults(); |
| 30 | + } |
| 31 | + |
| 32 | + private void SetupGame() |
| 33 | + { |
| 34 | + // First, allow the user to enter how many players are going |
| 35 | + // to play. This could be weird if the user enters negative |
| 36 | + // numbers, words, or too many players, so there are some |
| 37 | + // extra checks on the input to make sure the user didn't do |
| 38 | + // anything too crazy. Loop until the user enters valid input. |
| 39 | + bool validPlayerCount; |
| 40 | + int playerCount; |
| 41 | + do |
| 42 | + { |
| 43 | + Console.WriteLine(); |
| 44 | + Console.Write("HOW MANY PLAYERS? "); |
| 45 | + string? input = Console.ReadLine(); |
| 46 | + |
| 47 | + // assume the user has entered something incorrect - the |
| 48 | + // next steps will validate the input |
| 49 | + validPlayerCount = false; |
| 50 | + |
| 51 | + if (Int32.TryParse(input, out playerCount)) |
| 52 | + { |
| 53 | + if (playerCount > 0 && playerCount <= 20) |
| 54 | + { |
| 55 | + validPlayerCount = true; |
| 56 | + } |
| 57 | + else |
| 58 | + { |
| 59 | + Console.WriteLine("YOU MUST ENTER A NUMBER BETWEEN 1 AND 20!"); |
| 60 | + } |
| 61 | + } |
| 62 | + else |
| 63 | + { |
| 64 | + Console.WriteLine("YOU MUST ENTER A NUMBER"); |
| 65 | + } |
| 66 | + |
| 67 | + } |
| 68 | + while (!validPlayerCount); |
| 69 | + |
| 70 | + // Next, allow the user to enter names for the players; as each |
| 71 | + // name is entered, create a Player object to track the name |
| 72 | + // and their score, and save the object to the list in this class |
| 73 | + // so the rest of the game has access to the set of players |
| 74 | + for (int i = 0; i < playerCount; i++) |
| 75 | + { |
| 76 | + string? playerName = String.Empty; |
| 77 | + do |
| 78 | + { |
| 79 | + Console.Write($"NAME OF PLAYER #{i+1}? "); |
| 80 | + playerName = Console.ReadLine(); |
| 81 | + |
| 82 | + // names can be any sort of text, so allow whatever the user |
| 83 | + // enters as long as it isn't a blank space |
| 84 | + } |
| 85 | + while (String.IsNullOrWhiteSpace(playerName)); |
| 86 | + |
| 87 | + _players.Add(new Player(playerName)); |
| 88 | + } |
| 89 | + } |
| 90 | + |
| 91 | + private void PlayGame() |
| 92 | + { |
| 93 | + Random random = new Random(DateTime.Now.Millisecond); |
| 94 | + |
| 95 | + int round = 0; |
| 96 | + bool isOver = false; |
| 97 | + do |
| 98 | + { |
| 99 | + // starting a new round, increment the counter |
| 100 | + round++; |
| 101 | + Console.WriteLine($"ROUND {round}"); |
| 102 | + Console.WriteLine("--------------"); |
| 103 | + |
| 104 | + foreach (Player player in _players) |
| 105 | + { |
| 106 | + // ask the user how they want to throw |
| 107 | + Console.Write($"{player.Name.ToUpper()}'S THROW: "); |
| 108 | + string? input = Console.ReadLine(); |
| 109 | + |
| 110 | + // based on the input, figure out the probabilities |
| 111 | + int[] probabilities; |
| 112 | + switch (input) |
| 113 | + { |
| 114 | + case "1": |
| 115 | + { |
| 116 | + probabilities = new int[] { 65, 55, 50, 50 }; |
| 117 | + break; |
| 118 | + } |
| 119 | + case "2": |
| 120 | + { |
| 121 | + probabilities = new int[] { 99, 77, 43, 1 }; |
| 122 | + break; |
| 123 | + } |
| 124 | + case "3": |
| 125 | + { |
| 126 | + probabilities = new int[] { 95, 75, 45, 5 }; |
| 127 | + break; |
| 128 | + } |
| 129 | + default: |
| 130 | + { |
| 131 | + // in case the user types something bad, pretend it's |
| 132 | + // as if they tripped over themselves while throwing |
| 133 | + // the dart - they'll either hit a bullseye or completely |
| 134 | + // miss |
| 135 | + probabilities = new int[] { 95, 95, 95, 95 }; |
| 136 | + Console.Write("TRIP! "); |
| 137 | + break; |
| 138 | + } |
| 139 | + } |
| 140 | + |
| 141 | + |
| 142 | + // Next() returns a number in the range: min <= num < max, so specify 101 |
| 143 | + // as the maximum so that 100 is a number that could be returned |
| 144 | + int chance = random.Next(0, 101); |
| 145 | + |
| 146 | + if (chance > probabilities[0]) |
| 147 | + { |
| 148 | + player.Score += 40; |
| 149 | + Console.WriteLine("BULLSEYE!! 40 POINTS!"); |
| 150 | + } |
| 151 | + else if (chance > probabilities[1]) |
| 152 | + { |
| 153 | + player.Score += 30; |
| 154 | + Console.WriteLine("30-POINT ZONE!"); |
| 155 | + } |
| 156 | + else if (chance > probabilities[2]) |
| 157 | + { |
| 158 | + player.Score += 20; |
| 159 | + Console.WriteLine("20-POINT ZONE"); |
| 160 | + } |
| 161 | + else if (chance > probabilities[3]) |
| 162 | + { |
| 163 | + player.Score += 10; |
| 164 | + Console.WriteLine("WHEW! 10 POINTS."); |
| 165 | + } |
| 166 | + else |
| 167 | + { |
| 168 | + // missed it |
| 169 | + Console.WriteLine("MISSED THE TARGET! TOO BAD."); |
| 170 | + } |
| 171 | + |
| 172 | + // check to see if the player has won - if they have, then |
| 173 | + // break out of the loops |
| 174 | + if (player.Score > WinningScore) |
| 175 | + { |
| 176 | + Console.WriteLine(); |
| 177 | + Console.WriteLine("WE HAVE A WINNER!!"); |
| 178 | + Console.WriteLine($"{player.Name.ToUpper()} SCORED {player.Score} POINTS."); |
| 179 | + Console.WriteLine(); |
| 180 | + |
| 181 | + isOver = true; // out of the do/while round loop |
| 182 | + break; // out of the foreach (player) loop |
| 183 | + } |
| 184 | + |
| 185 | + Console.WriteLine(); |
| 186 | + } |
| 187 | + } |
| 188 | + while (!isOver); |
| 189 | + } |
| 190 | + |
| 191 | + private void PrintResults() |
| 192 | + { |
| 193 | + // For bragging rights, print out all the scores, but sort them |
| 194 | + // by who had the highest score |
| 195 | + var sorted = _players.OrderByDescending(p => p.Score); |
| 196 | + |
| 197 | + // padding is used to get things to line up nicely - the results |
| 198 | + // should look something like: |
| 199 | + // PLAYER SCORE |
| 200 | + // Bravo 210 |
| 201 | + // Charlie 15 |
| 202 | + // Alpha 1 |
| 203 | + Console.WriteLine("PLAYER SCORE"); |
| 204 | + foreach (var player in sorted) |
| 205 | + { |
| 206 | + Console.WriteLine($"{player.Name.PadRight(12)} {player.Score.ToString().PadLeft(5)}"); |
| 207 | + } |
| 208 | + |
| 209 | + Console.WriteLine(); |
| 210 | + Console.WriteLine("THANKS FOR THE GAME."); |
| 211 | + } |
| 212 | + |
| 213 | + private void PrintIntroduction() |
| 214 | + { |
| 215 | + Console.WriteLine(Title); |
| 216 | + Console.WriteLine(); |
| 217 | + Console.WriteLine(Introduction); |
| 218 | + Console.WriteLine(); |
| 219 | + Console.WriteLine(Operations); |
| 220 | + } |
| 221 | + |
| 222 | + private const string Title = @" |
| 223 | + BULLSEYE |
| 224 | + CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"; |
| 225 | + |
| 226 | + private const string Introduction = @" |
| 227 | +IN THIS GAME, UP TO 20 PLAYERS THROW DARTS AT A TARGET |
| 228 | +WITH 10, 20, 30, AND 40 POINT ZONES. THE OBJECTIVE IS |
| 229 | +TO GET 200 POINTS."; |
| 230 | + |
| 231 | + private const string Operations = @" |
| 232 | +THROW DESCRIPTION PROBABLE SCORE |
| 233 | + 1 FAST OVERARM BULLSEYE OR COMPLETE MISS |
| 234 | + 2 CONTROLLED OVERARM 10, 20, OR 30 POINTS |
| 235 | + 3 UNDERARM ANYTHING"; |
| 236 | + } |
| 237 | +} |
0 commit comments