diff --git a/18_Bullseye/csharp/Bullseye.csproj b/18_Bullseye/csharp/Bullseye.csproj
new file mode 100644
index 000000000..74abf5c97
--- /dev/null
+++ b/18_Bullseye/csharp/Bullseye.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/18_Bullseye/csharp/Bullseye.sln b/18_Bullseye/csharp/Bullseye.sln
new file mode 100644
index 000000000..2a65a4498
--- /dev/null
+++ b/18_Bullseye/csharp/Bullseye.sln
@@ -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
diff --git a/18_Bullseye/csharp/BullseyeGame.cs b/18_Bullseye/csharp/BullseyeGame.cs
new file mode 100644
index 000000000..58c9799d0
--- /dev/null
+++ b/18_Bullseye/csharp/BullseyeGame.cs
@@ -0,0 +1,237 @@
+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";
+ }
+}
diff --git a/18_Bullseye/csharp/Player.cs b/18_Bullseye/csharp/Player.cs
new file mode 100644
index 000000000..4d18fd435
--- /dev/null
+++ b/18_Bullseye/csharp/Player.cs
@@ -0,0 +1,28 @@
+namespace Bullseye
+{
+ ///
+ /// Object to track the name and score of a player
+ ///
+ public class Player
+ {
+ ///
+ /// Creates a play with the given name
+ ///
+ /// Name of the player
+ public Player(string name)
+ {
+ Name = name;
+ Score = 0;
+ }
+
+ ///
+ /// Name of the player
+ ///
+ public string Name { get; private set; }
+
+ ///
+ /// Current score of the player
+ ///
+ public int Score { get; set; }
+ }
+}
diff --git a/18_Bullseye/csharp/Program.cs b/18_Bullseye/csharp/Program.cs
new file mode 100644
index 000000000..1e4316ef6
--- /dev/null
+++ b/18_Bullseye/csharp/Program.cs
@@ -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();
+ }
+ }
+}