diff --git a/69_Pizza/csharp/Pizza/CustomerMap.cs b/69_Pizza/csharp/Pizza/CustomerMap.cs
new file mode 100644
index 00000000..ee991de3
--- /dev/null
+++ b/69_Pizza/csharp/Pizza/CustomerMap.cs
@@ -0,0 +1,131 @@
+using System.Text;
+
+namespace Pizza
+{
+ internal class CustomerMap
+ {
+ private readonly int _mapSize;
+ private readonly string[,] _customerMap;
+
+ public CustomerMap(int mapSize)
+ {
+ _mapSize = mapSize;
+ _customerMap = GenerateCustomerMap();
+ }
+
+ ///
+ /// Gets customer on position X, Y.
+ ///
+ /// Represents X position.
+ /// Represents Y position.
+ /// If positions is valid then returns customer name otherwise returns empty string.
+ public string GetCustomerOnPosition(int x, int y)
+ {
+ if(IsPositionOutOfRange(x, y))
+ {
+ return string.Empty;
+ }
+
+ return _customerMap[y, x];
+ }
+
+ ///
+ /// Overridden ToString for getting text representation of customers map.
+ ///
+ /// Text representation of customers map.
+ public override string ToString()
+ {
+ int verticalSpace = 4;
+ int horizontalSpace = 5;
+
+ var mapToDisplay = new StringBuilder();
+
+ AppendXLine(mapToDisplay, horizontalSpace);
+
+ for (int i = _customerMap.GetLength(0) - 1; i >= 0; i--)
+ {
+ mapToDisplay.AppendLine("-", verticalSpace);
+ mapToDisplay.Append($"{i + 1}");
+ mapToDisplay.Append(' ', horizontalSpace);
+
+ for (var j = 0; j < _customerMap.GetLength(1); j++)
+ {
+ mapToDisplay.Append($"{_customerMap[i, j]}");
+ mapToDisplay.Append(' ', horizontalSpace);
+ }
+
+ mapToDisplay.Append($"{i + 1}");
+ mapToDisplay.Append(' ', horizontalSpace);
+ mapToDisplay.Append(Environment.NewLine);
+ }
+
+ mapToDisplay.AppendLine("-", verticalSpace);
+
+ AppendXLine(mapToDisplay, horizontalSpace);
+
+ return mapToDisplay.ToString();
+ }
+
+ ///
+ /// Checks if position is out of range or not.
+ ///
+ /// Represents X position.
+ /// Represents Y position.
+ /// True if position is out of range otherwise false.
+ private bool IsPositionOutOfRange(int x, int y)
+ {
+ return
+ x < 0 || x > _mapSize - 1 ||
+ y < 0 || y > _mapSize - 1;
+ }
+
+ ///
+ /// Generates array which represents customers map.
+ ///
+ /// Returns customers map.
+ private string[,] GenerateCustomerMap()
+ {
+ string[,] customerMap = new string[_mapSize, _mapSize];
+ string[] customerNames = GetCustomerNames(_mapSize * _mapSize);
+ int currentCustomerNameIndex = 0;
+
+ for (int i = 0; i < customerMap.GetLength(0); i++)
+ {
+ for (int j = 0; j < customerMap.GetLength(1); j++)
+ {
+ customerMap[i, j] = customerNames[currentCustomerNameIndex++].ToString();
+ }
+ }
+
+ return customerMap;
+ }
+
+ ///
+ /// Generates customer names. Names are represented by alphanumerics from 'A'. Name of last customer depends on passed parameter.
+ ///
+ /// How many customers need to be generated.
+ /// List of customer names.
+ private static string[] GetCustomerNames(int numberOfCustomers)
+ {
+ // returns ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P"];
+ return Enumerable.Range(65, numberOfCustomers).Select(c => ((Char)c).ToString()).ToArray();
+ }
+
+ ///
+ /// Appends line with X coordinates.
+ ///
+ /// Current map where a new line will be appended.
+ /// Number of horizontal delimiters which will be added between each coordination.
+ private void AppendXLine(StringBuilder mapToDisplay, int horizontalSpace)
+ {
+ mapToDisplay.Append(' ');
+ mapToDisplay.Append('-', horizontalSpace);
+ for (var i = 0; i < _customerMap.GetLength(0); i++)
+ {
+ mapToDisplay.Append($"{i + 1}");
+ mapToDisplay.Append('-', horizontalSpace);
+ }
+ mapToDisplay.Append(Environment.NewLine);
+ }
+ }
+}
\ No newline at end of file
diff --git a/69_Pizza/csharp/Pizza/Pizza.csproj b/69_Pizza/csharp/Pizza/Pizza.csproj
new file mode 100644
index 00000000..74abf5c9
--- /dev/null
+++ b/69_Pizza/csharp/Pizza/Pizza.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/69_Pizza/csharp/Pizza/Pizza.sln b/69_Pizza/csharp/Pizza/Pizza.sln
new file mode 100644
index 00000000..91785a8c
--- /dev/null
+++ b/69_Pizza/csharp/Pizza/Pizza.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31912.275
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pizza", "Pizza.csproj", "{6AABE938-39C4-4661-AEA5-23CECA1DFEE1}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6AABE938-39C4-4661-AEA5-23CECA1DFEE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6AABE938-39C4-4661-AEA5-23CECA1DFEE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6AABE938-39C4-4661-AEA5-23CECA1DFEE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6AABE938-39C4-4661-AEA5-23CECA1DFEE1}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {8F7E9FAD-38C5-47A2-B5CA-2B6E5947B982}
+ EndGlobalSection
+EndGlobal
diff --git a/69_Pizza/csharp/Pizza/PizzaGame.cs b/69_Pizza/csharp/Pizza/PizzaGame.cs
new file mode 100644
index 00000000..22c78e05
--- /dev/null
+++ b/69_Pizza/csharp/Pizza/PizzaGame.cs
@@ -0,0 +1,296 @@
+namespace Pizza
+{
+ internal class PizzaGame
+ {
+ private const int CustomerMapSize = 4;
+ private readonly CustomerMap _customerMap = new CustomerMap(CustomerMapSize);
+
+ ///
+ /// Starts game. Main coordinator for pizza game.
+ /// It is responsible for showing information, getting data from user and starting to delivery pizza.
+ ///
+ public void Play()
+ {
+ ShowHeader();
+
+ string playerName = GetPlayerName();
+
+ ShowIntroduction(playerName);
+ ShowMap();
+
+ if (AskForMoreDirections())
+ {
+ ShowMoreDirections(playerName);
+
+ var playerUnderstands = AskIfPlayerUnderstand();
+ if (!playerUnderstands)
+ {
+ return;
+ }
+ }
+
+ StartDelivery(playerName);
+ EndDelivery(playerName);
+ }
+
+ ///
+ /// Starts with pizza delivering to customers.
+ /// Every 5 deliveries it is asking user whether want to continue in delivering.
+ ///
+ /// Player name which was filled by user.
+ private void StartDelivery(string playerName)
+ {
+ var numberOfDeliveredPizzas = 0;
+ while (true)
+ {
+ numberOfDeliveredPizzas++;
+ string deliverPizzaToCustomer = GetRandomCustomer();
+
+ WriteEmptyLine();
+ Console.WriteLine($"HELLO {playerName}'S PIZZA. THIS IS {deliverPizzaToCustomer}.");
+ Console.WriteLine("\tPLEASE SEND A PIZZA.");
+
+ DeliverPizzaByPlayer(playerName, deliverPizzaToCustomer);
+
+ if (numberOfDeliveredPizzas % 5 == 0)
+ {
+ bool playerWantToDeliveryMorePizzas = AskQuestionWithYesNoResponse("DO YOU WANT TO DELIVER MORE PIZZAS?");
+ if (!playerWantToDeliveryMorePizzas)
+ {
+ WriteEmptyLine();
+ break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets random customer for which pizza should be delivered.
+ ///
+ /// Customer name.
+ private string GetRandomCustomer()
+ {
+ int randomPositionOnX = Random.Shared.Next(0, CustomerMapSize);
+ int randomPositionOnY = Random.Shared.Next(0, CustomerMapSize);
+
+ return _customerMap.GetCustomerOnPosition(randomPositionOnX, randomPositionOnY);
+ }
+
+ ///
+ /// Delivers pizza to customer by player. It verifies whether player was delivering pizza to correct customer.
+ ///
+ /// Player name which was filled by user.
+ /// Customer name which order pizza.
+ private void DeliverPizzaByPlayer(string playerName, string deliverPizzaToCustomer)
+ {
+ while (true)
+ {
+ string userInput = GetPlayerInput($"\tDRIVER TO {playerName}: WHERE DOES {deliverPizzaToCustomer} LIVE?");
+ var deliveredToCustomer = GetCustomerFromPlayerInput(userInput);
+ if (string.IsNullOrEmpty(deliveredToCustomer))
+ {
+ deliveredToCustomer = "UNKNOWN CUSTOMER";
+ }
+
+ if (deliveredToCustomer.Equals(deliverPizzaToCustomer))
+ {
+ Console.WriteLine($"HELLO {playerName}. THIS IS {deliverPizzaToCustomer}, THANKS FOR THE PIZZA.");
+ break;
+ }
+
+ Console.WriteLine($"THIS IS {deliveredToCustomer}. I DID NOT ORDER A PIZZA.");
+ Console.WriteLine($"I LIVE AT {userInput}");
+ }
+ }
+
+ ///
+ /// Gets customer name by user input with customer coordinations.
+ ///
+ /// Input from users - it should represent customer coordination separated by ','.
+ /// If coordinations are correct and customer exists then returns true otherwise false.
+ private string GetCustomerFromPlayerInput(string userInput)
+ {
+ var pizzaIsDeliveredToPosition = userInput?
+ .Split(',')
+ .Select(i => int.TryParse(i, out var customerPosition) ? (customerPosition - 1) : -1)
+ .Where(i => i != -1)
+ .ToArray() ?? Array.Empty();
+ if (pizzaIsDeliveredToPosition.Length != 2)
+ {
+ return string.Empty;
+ }
+
+ return _customerMap.GetCustomerOnPosition(pizzaIsDeliveredToPosition[0], pizzaIsDeliveredToPosition[1]);
+ }
+
+ ///
+ /// Shows game header in console.
+ ///
+ private void ShowHeader()
+ {
+ Console.WriteLine("PIZZA".PadLeft(22));
+ Console.WriteLine("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
+ WriteEmptyLine(3);
+ Console.WriteLine("PIZZA DELIVERY GAME");
+ WriteEmptyLine();
+ }
+
+ ///
+ /// Asks user for name which will be used in game.
+ ///
+ /// Player name.
+ private string GetPlayerName()
+ {
+ return GetPlayerInput("WHAT IS YOUR FIRST NAME:");
+ }
+
+ ///
+ /// Shows game introduction in console
+ ///
+ /// Player name which was filled by user.
+ private void ShowIntroduction(string playerName)
+ {
+ Console.WriteLine($"HI, {playerName}. IN THIS GAME YOU ARE TO TAKE ORDERS");
+ Console.WriteLine("FOR PIZZAS. THEN YOU ARE TO TELL A DELIVERY BOY");
+ Console.WriteLine("WHERE TO DELIVER THE ORDERED PIZZAS.");
+ WriteEmptyLine(2);
+ }
+
+ ///
+ /// Shows customers map in console. In this method is used overridden method 'ToString' for getting text representation of customers map.
+ ///
+ private void ShowMap()
+ {
+ Console.WriteLine("MAP OF THE CITY OF HYATTSVILLE");
+ WriteEmptyLine();
+
+ Console.WriteLine(_customerMap.ToString());
+
+ Console.WriteLine("THE OUTPUT IS A MAP OF THE HOMES WHERE");
+ Console.WriteLine("YOU ARE TO SEND PIZZAS.");
+ WriteEmptyLine();
+ Console.WriteLine("YOUR JOB IS TO GIVE A TRUCK DRIVER");
+ Console.WriteLine("THE LOCATION OR COORDINATES OF THE");
+ Console.WriteLine("HOME ORDERING THE PIZZA.");
+ WriteEmptyLine();
+ }
+
+ ///
+ /// Asks user if needs more directions.
+ ///
+ /// True if user need more directions otherwise false.
+ private bool AskForMoreDirections()
+ {
+ var playerNeedsMoreDirections = AskQuestionWithYesNoResponse("DO YOU NEED MORE DIRECTIONS?");
+ WriteEmptyLine();
+
+ return playerNeedsMoreDirections;
+ }
+
+ ///
+ /// Shows more directions.
+ ///
+ /// Player name which was filled by user.
+ private void ShowMoreDirections(string playerName)
+ {
+ Console.WriteLine("SOMEBODY WILL ASK FOR A PIZZA TO BE");
+ Console.WriteLine("DELIVERED. THEN A DELIVERY BOY WILL");
+ Console.WriteLine("ASK YOU FOR THE LOCATION.");
+ Console.WriteLine("\tEXAMPLE:");
+ Console.WriteLine("THIS IS J. PLEASE SEND A PIZZA.");
+ Console.WriteLine($"DRIVER TO {playerName}. WHERE DOES J LIVE?");
+ Console.WriteLine("YOUR ANSWER WOULD BE 2,3");
+ }
+
+ ///
+ /// Asks user if understands to instructions.
+ ///
+ /// True if user understand otherwise false.
+ private bool AskIfPlayerUnderstand()
+ {
+ var playerUnderstands = AskQuestionWithYesNoResponse("UNDERSTAND?");
+ if (!playerUnderstands)
+ {
+ Console.WriteLine("THIS JOB IS DEFINITELY TOO DIFFICULT FOR YOU. THANKS ANYWAY");
+ return false;
+ }
+
+ WriteEmptyLine();
+ Console.WriteLine("GOOD. YOU ARE NOW READY TO START TAKING ORDERS.");
+ WriteEmptyLine();
+ Console.WriteLine("GOOD LUCK!!");
+ WriteEmptyLine();
+
+ return true;
+ }
+
+ ///
+ /// Shows message about ending delivery in console.
+ ///
+ /// Player name which was filled by user.
+ private void EndDelivery(string playerName)
+ {
+ Console.WriteLine($"O.K. {playerName}, SEE YOU LATER!");
+ WriteEmptyLine();
+ }
+
+ ///
+ /// Gets input from user.
+ ///
+ /// Question which is displayed in console.
+ /// User input.
+ private string GetPlayerInput(string question)
+ {
+ Console.Write($"{question} ");
+
+ while (true)
+ {
+ var userInput = Console.ReadLine();
+ if (!string.IsNullOrWhiteSpace(userInput))
+ {
+ return userInput;
+ }
+ }
+ }
+
+ ///
+ /// Asks user with required resposne 'YES', 'Y, 'NO', 'N'.
+ ///
+ /// Question which is displayed in console.
+ /// True if user write 'YES', 'Y'. False if user write 'NO', 'N'.
+ private static bool AskQuestionWithYesNoResponse(string question)
+ {
+ var possitiveResponse = new string[] { "Y", "YES" };
+ var negativeResponse = new string[] { "N", "NO" };
+ var validUserInputs = possitiveResponse.Concat(negativeResponse);
+
+ Console.Write($"{question} ");
+
+ string? userInput;
+ while (true)
+ {
+ userInput = Console.ReadLine();
+ if (!string.IsNullOrWhiteSpace(userInput) && validUserInputs.Contains(userInput.ToUpper()))
+ {
+ break;
+ }
+
+ Console.Write($"'YES' OR 'NO' PLEASE, NOW THEN, {question} ");
+ }
+
+ return possitiveResponse.Contains(userInput.ToUpper());
+ }
+
+ ///
+ /// Writes empty line in console.
+ ///
+ /// Number of empty lines which will be written in console. Parameter is optional and default value is 1.
+ private void WriteEmptyLine(int numberOfEmptyLines = 1)
+ {
+ for (int i = 0; i < numberOfEmptyLines; i++)
+ {
+ Console.WriteLine();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/69_Pizza/csharp/Pizza/Program.cs b/69_Pizza/csharp/Pizza/Program.cs
new file mode 100644
index 00000000..6c21fad0
--- /dev/null
+++ b/69_Pizza/csharp/Pizza/Program.cs
@@ -0,0 +1,11 @@
+namespace Pizza
+{
+ internal class Program
+ {
+ static void Main(string[] args)
+ {
+ var pizzaGame = new PizzaGame();
+ pizzaGame.Play();
+ }
+ }
+}
\ No newline at end of file
diff --git a/69_Pizza/csharp/Pizza/StringBuilderExtensions.cs b/69_Pizza/csharp/Pizza/StringBuilderExtensions.cs
new file mode 100644
index 00000000..f7cb828d
--- /dev/null
+++ b/69_Pizza/csharp/Pizza/StringBuilderExtensions.cs
@@ -0,0 +1,21 @@
+using System.Text;
+
+namespace Pizza
+{
+ internal static class StringBuilderExtensions
+ {
+ ///
+ /// Extensions for adding new lines of specific value.
+ ///
+ /// Extended class.
+ /// Value which will be repeated.
+ /// Number of lines that will be appended.
+ public static void AppendLine(this StringBuilder stringBuilder, string value, int numberOfLines)
+ {
+ for (int i = 0; i < numberOfLines; i++)
+ {
+ stringBuilder.AppendLine(value);
+ }
+ }
+ }
+}
\ No newline at end of file