Skip to content

Instantly share code, notes, and snippets.

@talatari
Last active March 12, 2024 05:59
Show Gist options
  • Save talatari/8a8714ed9719e53cd2c948b19bc96a6b to your computer and use it in GitHub Desktop.
Save talatari/8a8714ed9719e53cd2c948b19bc96a6b to your computer and use it in GitHub Desktop.
Task 50: CarService
namespace CarService
{
public static class Program
{
public static void Main()
{
PartFactory partFactory = new PartFactory();
CarFactory carFactory = new CarFactory(partFactory);
Queue<Car> cars = carFactory.CreateQueue();
CarService carService = new CarService(partFactory);
carService.Work(cars);
}
}
public static class UserUtils
{
private static readonly Random s_random = new();
public static int GetRandomNumber(int maxRange) =>
s_random.Next(0, maxRange);
public static int GetRandomNumber(int minRange, int maxRange) =>
s_random.Next(minRange, maxRange);
}
public class PartFactory
{
private readonly List<Part> _parts = new();
public PartFactory() =>
Init();
public List<Part> GetParts()
{
List<Part> parts = new();
foreach (Part part in _parts)
parts.Add(new Part(part.Name, part.Price));
return parts;
}
private void Init()
{
_parts.Add(new Part("Steering rack", 25000));
_parts.Add(new Part("Brake pad", 11250));
_parts.Add(new Part("Air filter", 2250));
_parts.Add(new Part("Oil filter", 750));
_parts.Add(new Part("Generator", 20000));
_parts.Add(new Part("Carburetor", 15000));
_parts.Add(new Part("Shock absorber", 12500));
_parts.Add(new Part("Carputer", 10000));
}
}
public class Part
{
public Part(string name, int price)
{
Name = name;
Price = price;
IsBroken = false;
}
public string Name { get; }
public int Price { get; }
public bool IsBroken { get; private set; }
public Part Clone() =>
new(Name, Price);
public void MakeBroken() =>
IsBroken = true;
}
public class CarFactory
{
private readonly Queue<Car> _cars = new();
private readonly PartFactory _partFactory;
public CarFactory(PartFactory partFactory) =>
_partFactory = partFactory;
public Queue<Car> CreateQueue()
{
int minCarRange = 15;
int maxCarRange = 25;
int amountCars = UserUtils.GetRandomNumber(minCarRange, maxCarRange);
for (int i = 0; i < amountCars; i++)
_cars.Enqueue(new Car(_partFactory.GetParts()));
return _cars;
}
}
public class Car
{
private readonly List<Part> _parts;
public Car(List<Part> parts)
{
_parts = parts;
MakeBrokenPart();
}
public void ShowBrokenPart()
{
foreach (Part part in _parts)
if (part.IsBroken)
Console.WriteLine($"Broken part: {part.Name}");
}
public bool TryGetBrokenPart(out Part brokenPart)
{
foreach (Part part in _parts)
if (part.IsBroken)
{
brokenPart = part;
return true;
}
brokenPart = null;
return false;
}
public void Change(Part workPart)
{
foreach (Part part in _parts)
if (part == workPart)
{
_parts.Remove(part);
_parts.Add(workPart);
return;
}
}
private void MakeBrokenPart()
{
int indexPart = UserUtils.GetRandomNumber(_parts.Count);
_parts[indexPart].MakeBroken();
}
}
public class Storage
{
private readonly List<Cell> _cells = new();
public Storage(List<Part> parts) =>
Init(parts);
public void ShowAmount()
{
Console.WriteLine("\n[Storage]");
Console.WriteLine("Part: \t\t\tPrice: \t\tAmount:");
foreach (Cell cell in _cells)
cell.Show();
Console.WriteLine();
}
public bool HaveAvailable(Part brokenPart)
{
foreach (Cell storagePart in _cells)
if (storagePart.Part.Name == brokenPart.Name)
return true;
return false;
}
public bool TryGetWorkPart(Part brokenPart, out Part workPart)
{
foreach (Cell storagePart in _cells)
if (storagePart.Part.Name == brokenPart.Name)
{
workPart = storagePart.Part.Clone();
storagePart.DecreaseAmount();
if (storagePart.Amount == 0)
_cells.Remove(storagePart);
return true;
}
workPart = null;
return false;
}
private void Init(List<Part> parts)
{
int minAmountPart = 1;
int maxAmountPart = 3;
foreach (Part part in parts)
_cells.Add(new Cell(part, UserUtils.GetRandomNumber(minAmountPart, maxAmountPart)));
}
}
public class Cell
{
public Cell(Part part, int amount)
{
Part = part;
Amount = amount;
}
public Part Part { get; }
public int Amount { get; private set; }
public void DecreaseAmount() =>
Amount--;
public void Show() =>
Console.WriteLine($"{Part.Name}\t\t{Part.Price}\t\t{Amount}");
}
public class CarService
{
private readonly Storage _storage;
private int _money = 20000;
private int _totalPrice;
private int _workPrice;
private Queue<Car> _cars = new();
public CarService(PartFactory partFactory) =>
_storage = new Storage(partFactory.GetParts());
public void Work(Queue<Car> cars)
{
_cars = cars;
while (_cars.Count > 0)
{
Console.Clear();
Car car = _cars.Dequeue();
ShowBalance();
ShowNext(car);
_storage.ShowAmount();
RequestAcceptForRepair();
if (car.TryGetBrokenPart(out Part workenPart))
{
CalculationPrice(workenPart.Price);
RepairBrokenPart(car, workenPart);
}
Console.ReadKey();
}
}
private void ShowBalance() =>
Console.WriteLine($"[CarService 'Second Life']\nBalance: {_money}\n");
private void ShowNext(Car car)
{
Console.Write($"[Queue: {_cars.Count} cars]\n" +
$"Next car in queue with ");
car.ShowBrokenPart();
}
private void CalculationPrice(int brokenPartPrice)
{
int normalizedPercent = 100;
int percent = 20;
_workPrice = brokenPartPrice / normalizedPercent * percent;
_totalPrice = brokenPartPrice + _workPrice;
Console.WriteLine($"Total price = {_totalPrice} (price for work = {_workPrice})");
}
private void RequestAcceptForRepair()
{
Console.Write("For repair press any key...");
Console.ReadKey();
}
private void RepairBrokenPart(Car car, Part brokenPart)
{
if (HaveAmountAvailable(brokenPart))
if (TryRepair(car, brokenPart))
Payment();
else
CompensatesForDamage();
else
PayFine();
}
private bool HaveAmountAvailable(Part brokenPart) =>
_storage.HaveAvailable(brokenPart);
private bool TryRepair(Car car, Part brokenPart)
{
int minRange = 1;
int maxRange = 10;
if (UserUtils.GetRandomNumber(minRange, maxRange) == minRange)
return false;
if (_storage.TryGetWorkPart(brokenPart, out Part workPart))
{
car.Change(workPart);
return true;
}
return false;
}
private void Payment()
{
Console.WriteLine($"The repair was completed successfully. \n" +
$"CarService is working {_totalPrice}\n");
_money += _totalPrice;
}
private void CompensatesForDamage()
{
Console.WriteLine($"The part could not be repaired. \n" +
$"Compensation in the amount of {_workPrice}\n");
_money -= _workPrice;
}
private void PayFine()
{
Console.WriteLine($"\nNecessary part is missing in the storage. \n" +
$"Paid a fine in the amount of {_workPrice}");
_money -= _workPrice;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment