Files
basic-computer-games/69_Pizza/csharp/Pizza/PizzaGame.cs
2022-01-09 18:51:34 +01:00

296 lines
11 KiB
C#

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();
}
}
}
}