diff --git a/54_Letter/csharp/Game.cs b/54_Letter/csharp/Game.cs
new file mode 100644
index 00000000..e7d525c9
--- /dev/null
+++ b/54_Letter/csharp/Game.cs
@@ -0,0 +1,137 @@
+namespace Letter
+{
+ internal static class Game
+ {
+ ///
+ /// Maximum number of guesses.
+ /// Note the program doesn't enforce this - it just displays a message if this is exceeded.
+ ///
+ private const int MaximumGuesses = 5;
+
+ ///
+ /// Main game loop.
+ ///
+ public static void Play()
+ {
+ DisplayIntroductionText();
+
+ // Keep playing forever, or until the user quits.
+ while (true)
+ {
+ PlayRound();
+ }
+ }
+
+ ///
+ /// Play a single round.
+ ///
+ internal static void PlayRound()
+ {
+ var gameState = new GameState();
+ DisplayRoundIntroduction();
+
+ char letterInput = '\0'; // Set the initial character to something that's not A-Z.
+ while (letterInput != gameState.Letter)
+ {
+ letterInput = GetCharacterFromKeyboard();
+ gameState.GuessesSoFar++;
+ DisplayGuessResult(gameState.Letter, letterInput);
+ }
+ DisplaySuccessMessage(gameState);
+ }
+
+ ///
+ /// Display an introduction when the game loads.
+ ///
+ internal static void DisplayIntroductionText()
+ {
+ Console.ForegroundColor = ConsoleColor.Yellow;
+ Console.WriteLine("LETTER");
+ Console.WriteLine("Creative Computing, Morristown, New Jersey.");
+ Console.WriteLine("");
+
+ Console.ForegroundColor = ConsoleColor.DarkGreen;
+ Console.WriteLine("Letter Guessing Game");
+ Console.WriteLine("I'll think of a letter of the alphabet, A to Z.");
+ Console.WriteLine("Try to guess my letter and I'll give you clues");
+ Console.WriteLine("as to how close you're getting to my letter.");
+ Console.WriteLine("");
+
+ Console.ResetColor();
+ }
+
+ ///
+ /// Display introductionary text for each round.
+ ///
+ internal static void DisplayRoundIntroduction()
+ {
+ Console.ForegroundColor = ConsoleColor.Yellow;
+ Console.WriteLine("O.K., I have a letter. Start guessing.");
+
+ Console.ResetColor();
+ }
+
+ ///
+ /// Display text depending whether the guess is lower or higher.
+ ///
+ internal static void DisplayGuessResult(char letterToGuess, char letterInput)
+ {
+ Console.BackgroundColor = ConsoleColor.White;
+ Console.ForegroundColor = ConsoleColor.Black;
+ Console.Write(" " + letterInput + " ");
+
+ Console.ResetColor();
+ Console.ForegroundColor = ConsoleColor.Gray;
+ Console.Write(" ");
+ if (letterInput != letterToGuess)
+ {
+ if (letterInput > letterToGuess)
+ {
+ Console.WriteLine("Too high. Try a lower letter");
+ }
+ else
+ {
+ Console.WriteLine("Too low. Try a higher letter");
+ }
+ }
+ Console.ResetColor();
+ }
+
+ ///
+ /// Display success, and the number of guesses.
+ ///
+ internal static void DisplaySuccessMessage(GameState gameState)
+ {
+ Console.ForegroundColor = ConsoleColor.Green;
+ Console.WriteLine($"You got it in {gameState.GuessesSoFar} guesses!!");
+ if (gameState.GuessesSoFar > MaximumGuesses)
+ {
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.WriteLine($"But it shouldn't take more than {MaximumGuesses} guesses!");
+ }
+ else
+ {
+ Console.WriteLine("Good job !!!!!");
+ }
+ Console.ForegroundColor = ConsoleColor.Yellow;
+ Console.WriteLine("");
+ Console.WriteLine("Let's play again.....");
+
+ Console.ResetColor();
+ }
+
+ ///
+ /// Get valid input from the keyboard: must be an alpha character. Converts to upper case if necessary.
+ ///
+ internal static char GetCharacterFromKeyboard()
+ {
+ char letterInput;
+ do
+ {
+ var keyPressed = Console.ReadKey(true);
+ letterInput = Char.ToUpper(keyPressed.KeyChar); // Convert to upper case immediately.
+ } while (!Char.IsLetter(letterInput)); // If the input is not a letter, wait for another letter to be pressed.
+ return letterInput;
+ }
+ }
+}
diff --git a/54_Letter/csharp/GameState.cs b/54_Letter/csharp/GameState.cs
new file mode 100644
index 00000000..02aa38b1
--- /dev/null
+++ b/54_Letter/csharp/GameState.cs
@@ -0,0 +1,37 @@
+namespace Letter
+{
+ ///
+ /// Holds the current state.
+ ///
+ internal class GameState
+ {
+ ///
+ /// Initialise the game state with a random letter.
+ ///
+ public GameState()
+ {
+ Letter = GetRandomLetter();
+ GuessesSoFar = 0;
+ }
+
+ ///
+ /// The letter that the user is guessing.
+ ///
+ public char Letter { get; set; }
+
+ ///
+ /// The number of guesses the user has had so far.
+ ///
+ public int GuessesSoFar { get; set; }
+
+ ///
+ /// Get a random character (A-Z) for the user to guess.
+ ///
+ internal static char GetRandomLetter()
+ {
+ var random = new Random();
+ var randomNumber = random.Next(0, 26);
+ return (char)('A' + randomNumber);
+ }
+ }
+}
diff --git a/54_Letter/csharp/Program.cs b/54_Letter/csharp/Program.cs
new file mode 100644
index 00000000..9a1c29db
--- /dev/null
+++ b/54_Letter/csharp/Program.cs
@@ -0,0 +1,3 @@
+using Letter;
+
+Game.Play();
\ No newline at end of file