Skip to content

Instantly share code, notes, and snippets.

@talatari
Forked from adamkruver/Task 50: CarService
Last active January 17, 2024 10:27
Show Gist options
  • Save talatari/63e5c27103fdb759bb77f7e1875d9460 to your computer and use it in GitHub Desktop.
Save talatari/63e5c27103fdb759bb77f7e1875d9460 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++)
{
List<Part> parts = _partFactory.GetParts();
_cars.Enqueue(new Car(parts));
}
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 int _money = 20000;
private int _totalPrice;
private int _workPrice;
private readonly Storage _storage;
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 brokenPart))
{
CalculationPrice(brokenPart.Price);
RepairBrokenPart(car, brokenPart);
}
Console.ReadKey();
}
}
private void ShowBalance() => Console.WriteLine($"[CarService 'Second Life']\n" +
$"Balance: {_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