Add pizza implementation in c#

This commit is contained in:
Flow
2022-01-09 18:51:34 +01:00
parent 3efbb9164c
commit dedca6ac0d
6 changed files with 494 additions and 0 deletions

View File

@@ -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();
}
/// <summary>
/// Gets customer on position X, Y.
/// </summary>
/// <param name="x">Represents X position.</param>
/// <param name="y">Represents Y position.</param>
/// <returns>If positions is valid then returns customer name otherwise returns empty string.</returns>
public string GetCustomerOnPosition(int x, int y)
{
if(IsPositionOutOfRange(x, y))
{
return string.Empty;
}
return _customerMap[y, x];
}
/// <summary>
/// Overridden ToString for getting text representation of customers map.
/// </summary>
/// <returns>Text representation of customers map.</returns>
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();
}
/// <summary>
/// Checks if position is out of range or not.
/// </summary>
/// <param name="x">Represents X position.</param>
/// <param name="y">Represents Y position.</param>
/// <returns>True if position is out of range otherwise false.</returns>
private bool IsPositionOutOfRange(int x, int y)
{
return
x < 0 || x > _mapSize - 1 ||
y < 0 || y > _mapSize - 1;
}
/// <summary>
/// Generates array which represents customers map.
/// </summary>
/// <returns>Returns customers map.</returns>
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;
}
/// <summary>
/// Generates customer names. Names are represented by alphanumerics from 'A'. Name of last customer depends on passed parameter.
/// </summary>
/// <param name="numberOfCustomers">How many customers need to be generated.</param>
/// <returns>List of customer names.</returns>
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();
}
/// <summary>
/// Appends line with X coordinates.
/// </summary>
/// <param name="mapToDisplay">Current map where a new line will be appended.</param>
/// <param name="horizontalSpace">Number of horizontal delimiters which will be added between each coordination.</param>
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);
}
}
}

View 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>

View File

@@ -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

View File

@@ -0,0 +1,296 @@
namespace Pizza
{
internal class PizzaGame
{
private const int CustomerMapSize = 4;
private readonly CustomerMap _customerMap = new CustomerMap(CustomerMapSize);
/// <summary>
/// Starts game. Main coordinator for pizza game.
/// It is responsible for showing information, getting data from user and starting to delivery pizza.
/// </summary>
public void Play()
{
ShowHeader();
string playerName = GetPlayerName();
ShowIntroduction(playerName);
ShowMap();
if (AskForMoreDirections())
{
ShowMoreDirections(playerName);
var playerUnderstands = AskIfPlayerUnderstand();
if (!playerUnderstands)
{
return;
}
}
StartDelivery(playerName);
EndDelivery(playerName);
}
/// <summary>
/// Starts with pizza delivering to customers.
/// Every 5 deliveries it is asking user whether want to continue in delivering.
/// </summary>
/// <param name="playerName">Player name which was filled by user.</param>
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;
}
}
}
}
/// <summary>
/// Gets random customer for which pizza should be delivered.
/// </summary>
/// <returns>Customer name.</returns>
private string GetRandomCustomer()
{
int randomPositionOnX = Random.Shared.Next(0, CustomerMapSize);
int randomPositionOnY = Random.Shared.Next(0, CustomerMapSize);
return _customerMap.GetCustomerOnPosition(randomPositionOnX, randomPositionOnY);
}
/// <summary>
/// Delivers pizza to customer by player. It verifies whether player was delivering pizza to correct customer.
/// </summary>
/// <param name="playerName">Player name which was filled by user.</param>
/// <param name="deliverPizzaToCustomer">Customer name which order pizza.</param>
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}");
}
}
/// <summary>
/// Gets customer name by user input with customer coordinations.
/// </summary>
/// <param name="userInput">Input from users - it should represent customer coordination separated by ','.</param>
/// <returns>If coordinations are correct and customer exists then returns true otherwise false.</returns>
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<int>();
if (pizzaIsDeliveredToPosition.Length != 2)
{
return string.Empty;
}
return _customerMap.GetCustomerOnPosition(pizzaIsDeliveredToPosition[0], pizzaIsDeliveredToPosition[1]);
}
/// <summary>
/// Shows game header in console.
/// </summary>
private void ShowHeader()
{
Console.WriteLine("PIZZA".PadLeft(22));
Console.WriteLine("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
WriteEmptyLine(3);
Console.WriteLine("PIZZA DELIVERY GAME");
WriteEmptyLine();
}
/// <summary>
/// Asks user for name which will be used in game.
/// </summary>
/// <returns>Player name.</returns>
private string GetPlayerName()
{
return GetPlayerInput("WHAT IS YOUR FIRST NAME:");
}
/// <summary>
/// Shows game introduction in console
/// </summary>
/// <param name="playerName">Player name which was filled by user.</param>
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);
}
/// <summary>
/// Shows customers map in console. In this method is used overridden method 'ToString' for getting text representation of customers map.
/// </summary>
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();
}
/// <summary>
/// Asks user if needs more directions.
/// </summary>
/// <returns>True if user need more directions otherwise false.</returns>
private bool AskForMoreDirections()
{
var playerNeedsMoreDirections = AskQuestionWithYesNoResponse("DO YOU NEED MORE DIRECTIONS?");
WriteEmptyLine();
return playerNeedsMoreDirections;
}
/// <summary>
/// Shows more directions.
/// </summary>
/// <param name="playerName">Player name which was filled by user.</param>
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");
}
/// <summary>
/// Asks user if understands to instructions.
/// </summary>
/// <returns>True if user understand otherwise false.</returns>
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;
}
/// <summary>
/// Shows message about ending delivery in console.
/// </summary>
/// <param name="playerName">Player name which was filled by user.</param>
private void EndDelivery(string playerName)
{
Console.WriteLine($"O.K. {playerName}, SEE YOU LATER!");
WriteEmptyLine();
}
/// <summary>
/// Gets input from user.
/// </summary>
/// <param name="question">Question which is displayed in console.</param>
/// <returns>User input.</returns>
private string GetPlayerInput(string question)
{
Console.Write($"{question} ");
while (true)
{
var userInput = Console.ReadLine();
if (!string.IsNullOrWhiteSpace(userInput))
{
return userInput;
}
}
}
/// <summary>
/// Asks user with required resposne 'YES', 'Y, 'NO', 'N'.
/// </summary>
/// <param name="question">Question which is displayed in console.</param>
/// <returns>True if user write 'YES', 'Y'. False if user write 'NO', 'N'.</returns>
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());
}
/// <summary>
/// Writes empty line in console.
/// </summary>
/// <param name="numberOfEmptyLines">Number of empty lines which will be written in console. Parameter is optional and default value is 1.</param>
private void WriteEmptyLine(int numberOfEmptyLines = 1)
{
for (int i = 0; i < numberOfEmptyLines; i++)
{
Console.WriteLine();
}
}
}
}

View File

@@ -0,0 +1,11 @@
namespace Pizza
{
internal class Program
{
static void Main(string[] args)
{
var pizzaGame = new PizzaGame();
pizzaGame.Play();
}
}
}

View File

@@ -0,0 +1,21 @@
using System.Text;
namespace Pizza
{
internal static class StringBuilderExtensions
{
/// <summary>
/// Extensions for adding new lines of specific value.
/// </summary>
/// <param name="stringBuilder">Extended class.</param>
/// <param name="value">Value which will be repeated.</param>
/// <param name="numberOfLines">Number of lines that will be appended.</param>
public static void AppendLine(this StringBuilder stringBuilder, string value, int numberOfLines)
{
for (int i = 0; i < numberOfLines; i++)
{
stringBuilder.AppendLine(value);
}
}
}
}