diff --git a/91_Train/csharp/Train/Train.sln b/91_Train/csharp/Train/Train.sln
new file mode 100644
index 00000000..7735a737
--- /dev/null
+++ b/91_Train/csharp/Train/Train.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31129.286
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TrainGame", "Train\TrainGame.csproj", "{42617537-4E7C-4082-A17B-7F18DFA04C35}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TrainTests", "..\TrainTests\TrainTests\TrainTests.csproj", "{7C740A47-99C6-44E1-BDEE-140086BCFE8B}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {42617537-4E7C-4082-A17B-7F18DFA04C35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {42617537-4E7C-4082-A17B-7F18DFA04C35}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {42617537-4E7C-4082-A17B-7F18DFA04C35}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {42617537-4E7C-4082-A17B-7F18DFA04C35}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7C740A47-99C6-44E1-BDEE-140086BCFE8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7C740A47-99C6-44E1-BDEE-140086BCFE8B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7C740A47-99C6-44E1-BDEE-140086BCFE8B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7C740A47-99C6-44E1-BDEE-140086BCFE8B}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {919F73B8-DE34-4992-9B05-E1FEC2D2F7C6}
+ EndGlobalSection
+EndGlobal
diff --git a/91_Train/csharp/Train/Train/TrainGame.cs b/91_Train/csharp/Train/Train/TrainGame.cs
new file mode 100644
index 00000000..98e0db68
--- /dev/null
+++ b/91_Train/csharp/Train/Train/TrainGame.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Linq;
+
+namespace Train
+{
+ public class TrainGame
+ {
+ private Random Rnd { get; } = new Random();
+ private readonly int ALLOWED_PERCENTAGE_DIFFERENCE = 5;
+
+ static void Main()
+ {
+ TrainGame train = new TrainGame();
+ train.GameLoop();
+ }
+
+ public void GameLoop()
+ {
+ DisplayIntroText();
+
+ do
+ {
+ PlayGame();
+ } while (TryAgain());
+ }
+
+ private void PlayGame()
+ {
+ int carSpeed = (int)GenerateRandomNumber(40, 25);
+ int timeDifference = (int)GenerateRandomNumber(5, 15);
+ int trainSpeed = (int)GenerateRandomNumber(20, 19);
+
+ Console.WriteLine($"A CAR TRAVELING {carSpeed} MPH CAN MAKE A CERTAIN TRIP IN");
+ Console.WriteLine($"{timeDifference} HOURS LESS THAN A TRAIN TRAVELING AT {trainSpeed} MPH");
+ Console.WriteLine("HOW LONG DOES THE TRIP TAKE BY CAR?");
+
+ double userInputCarJourneyDuration = double.Parse(Console.ReadLine());
+ double actualCarJourneyDuration = CalculateCarJourneyDuration(carSpeed, timeDifference, trainSpeed);
+ int percentageDifference = CalculatePercentageDifference(userInputCarJourneyDuration, actualCarJourneyDuration);
+
+ if (IsWithinAllowedDifference(percentageDifference, ALLOWED_PERCENTAGE_DIFFERENCE))
+ {
+ Console.WriteLine($"GOOD! ANSWER WITHIN {percentageDifference} PERCENT.");
+ }
+ else
+ {
+ Console.WriteLine($"SORRY. YOU WERE OFF BY {percentageDifference} PERCENT.");
+ }
+ Console.WriteLine($"CORRECT ANSWER IS {actualCarJourneyDuration} HOURS.");
+ }
+
+ public static bool IsWithinAllowedDifference(int percentageDifference, int allowedDifference)
+ {
+ return percentageDifference <= allowedDifference;
+ }
+
+ private static int CalculatePercentageDifference(double userInputCarJourneyDuration, double carJourneyDuration)
+ {
+ return (int)(Math.Abs((carJourneyDuration - userInputCarJourneyDuration) * 100 / userInputCarJourneyDuration) + .5);
+ }
+
+ public static double CalculateCarJourneyDuration(double carSpeed, double timeDifference, double trainSpeed)
+ {
+ return timeDifference * trainSpeed / (carSpeed - trainSpeed);
+ }
+
+ public double GenerateRandomNumber(int baseSpeed, int multiplier)
+ {
+ return multiplier * Rnd.NextDouble() + baseSpeed;
+ }
+
+ private bool TryAgain()
+ {
+ Console.WriteLine("ANOTHER PROBLEM (YES OR NO)? ");
+ return IsInputYes(Console.ReadLine());
+ }
+
+ public static bool IsInputYes(string consoleInput)
+ {
+ var options = new string[] { "Y", "YES" };
+ return options.Any(o => o.Equals(consoleInput, StringComparison.CurrentCultureIgnoreCase));
+ }
+
+ private void DisplayIntroText()
+ {
+ Console.WriteLine("TRAIN");
+ Console.WriteLine("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ Console.WriteLine();
+ Console.WriteLine("TIME - SPEED DISTANCE EXERCISE");
+ Console.WriteLine();
+ }
+ }
+}
diff --git a/91_Train/csharp/Train/Train/TrainGame.csproj b/91_Train/csharp/Train/Train/TrainGame.csproj
new file mode 100644
index 00000000..c73e0d16
--- /dev/null
+++ b/91_Train/csharp/Train/Train/TrainGame.csproj
@@ -0,0 +1,8 @@
+
+
+
+ Exe
+ netcoreapp3.1
+
+
+
diff --git a/91_Train/csharp/TrainTests/TrainTests/TrainGameTests.cs b/91_Train/csharp/TrainTests/TrainTests/TrainGameTests.cs
new file mode 100644
index 00000000..a9804283
--- /dev/null
+++ b/91_Train/csharp/TrainTests/TrainTests/TrainGameTests.cs
@@ -0,0 +1,53 @@
+using Train;
+using Xunit;
+
+namespace TrainTests
+{
+ public class TrainGameTests
+ {
+ [Fact]
+ public void MiniumRandomNumber()
+ {
+ TrainGame game = new TrainGame();
+ Assert.True(game.GenerateRandomNumber(10, 10) >= 10);
+ }
+
+ [Fact]
+ public void MaximumRandomNumber()
+ {
+ TrainGame game = new TrainGame();
+ Assert.True(game.GenerateRandomNumber(10, 10) <= 110);
+ }
+
+ [Fact]
+ public void IsInputYesWhenY()
+ {
+ Assert.True(TrainGame.IsInputYes("y"));
+ }
+
+ [Fact]
+ public void IsInputYesWhenNotY()
+ {
+ Assert.False(TrainGame.IsInputYes("a"));
+ }
+
+ [Fact]
+ public void CarDurationTest()
+ {
+ Assert.Equal(1, TrainGame.CalculateCarJourneyDuration(30, 1, 15) );
+ }
+
+ [Fact]
+ public void IsWithinAllowedDifference()
+ {
+ Assert.True(TrainGame.IsWithinAllowedDifference(5,5));
+ }
+
+
+ [Fact]
+ public void IsNotWithinAllowedDifference()
+ {
+ Assert.False(TrainGame.IsWithinAllowedDifference(6, 5));
+ }
+ }
+}
diff --git a/91_Train/csharp/TrainTests/TrainTests/TrainTests.csproj b/91_Train/csharp/TrainTests/TrainTests/TrainTests.csproj
new file mode 100644
index 00000000..a8de6dde
--- /dev/null
+++ b/91_Train/csharp/TrainTests/TrainTests/TrainTests.csproj
@@ -0,0 +1,26 @@
+
+
+
+ netcoreapp3.1
+
+ false
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+