mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-23 15:37:51 -08:00
C# implementation of Bullseye
This commit is contained in:
10
18_Bullseye/csharp/Bullseye.csproj
Normal file
10
18_Bullseye/csharp/Bullseye.csproj
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
22
18_Bullseye/csharp/Bullseye.sln
Normal file
22
18_Bullseye/csharp/Bullseye.sln
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 16
|
||||||
|
VisualStudioVersion = 16.0.30114.105
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bullseye", "Bullseye.csproj", "{04C164DB-594F-41C4-BC0E-0A203A5536C7}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{04C164DB-594F-41C4-BC0E-0A203A5536C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{04C164DB-594F-41C4-BC0E-0A203A5536C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{04C164DB-594F-41C4-BC0E-0A203A5536C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{04C164DB-594F-41C4-BC0E-0A203A5536C7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
237
18_Bullseye/csharp/BullseyeGame.cs
Normal file
237
18_Bullseye/csharp/BullseyeGame.cs
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
namespace Bullseye
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class encompassing the game
|
||||||
|
/// </summary>
|
||||||
|
public class BullseyeGame
|
||||||
|
{
|
||||||
|
private readonly List<Player> _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<Player>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
}
|
||||||
28
18_Bullseye/csharp/Player.cs
Normal file
28
18_Bullseye/csharp/Player.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
namespace Bullseye
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Object to track the name and score of a player
|
||||||
|
/// </summary>
|
||||||
|
public class Player
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a play with the given name
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Name of the player</param>
|
||||||
|
public Player(string name)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Score = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Name of the player
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Current score of the player
|
||||||
|
/// </summary>
|
||||||
|
public int Score { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
14
18_Bullseye/csharp/Program.cs
Normal file
14
18_Bullseye/csharp/Program.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Bullseye
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
// Entry point to the application; create an instance of the
|
||||||
|
// game class and call Run()
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
new BullseyeGame().Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user