Skip to content

Instantly share code, notes, and snippets.

@GigaOrts
Last active March 21, 2024 16:54
Show Gist options
  • Save GigaOrts/3fdf3c24a19e903c13b5c1459208547b to your computer and use it in GitHub Desktop.
Save GigaOrts/3fdf3c24a19e903c13b5c1459208547b to your computer and use it in GitHub Desktop.
using CarAssembly;
using DetailAssembly;
using ServiceAssembly;
using StorageAssembly;
using WalletAssembly;
using InputValidatorAssembly;
namespace ClientAutoservice
{
class Program
{
static void Main()
{
var detailFabric = new DetailFabric();
List<Detail> details = detailFabric.Create();
var storage = new Storage(details, detailFabric.DetailPrefabs);
var carFabric = new CarFabric(detailFabric);
List<Car> cars = carFabric.Create(3);
var queue = new Queue<Car>(cars);
var wallet = new Wallet(100);
var service = new Service(storage, wallet);
bool isRunning = true;
bool isGameOver = false;
while (isRunning && isGameOver == false)
{
Console.WriteLine($"{(int)Command.Serve} - Serve client");
Console.WriteLine($"{(int)Command.Refuse} - Refuse client");
Console.WriteLine($"{(int)Command.Exit} - Exit the program");
Car currentCar = queue.Peek();
string frame = new string('-', 30);
Console.WriteLine(frame);
Console.WriteLine(wallet);
Console.WriteLine(frame);
storage.Show();
Console.WriteLine(frame);
Console.WriteLine(currentCar);
Console.Write("Choose command: ");
if (Enum.TryParse(Console.ReadLine(), out Command command) == false)
{
Console.WriteLine("Invalid operation");
continue;
}
switch (command)
{
case Command.Serve:
service.Serve(currentCar);
break;
case Command.Refuse:
service.Refuse();
break;
case Command.Exit:
isRunning = false;
break;
}
queue.Dequeue();
isGameOver = wallet.IsEmpty || queue.Count == 0;
Console.WriteLine("\nPress any button...");
Console.ReadKey();
Console.Clear();
}
Console.WriteLine("Bye!");
}
}
enum Command
{
None,
Serve,
Refuse,
Exit
}
}
namespace InputValidatorAssembly
{
static class InputValidator
{
public static bool InRange(int number, int min, int max)
{
if ((number >= min && number < max) == false)
{
Console.WriteLine("!!! Wrong input, out of range. Car gone...");
return false;
}
return true;
}
public static bool TryReadInt(out int input)
{
Console.Write("Choose detail from storage: ");
if (int.TryParse(Console.ReadLine(), out input) == false)
{
Console.WriteLine("!!! Wrong input, should be a digit. Car gone...");
return false;
}
return true;
}
}
}
namespace ServiceAssembly
{
class Service
{
private readonly double _jobPriceFactor = 1.3f;
private readonly int _penalty = 30;
private Storage _storage;
private Wallet _wallet;
public Service(Storage storage, Wallet wallet)
{
_storage = storage;
_wallet = wallet;
}
public void Serve(Car car)
{
bool isDigit = InputValidator.TryReadInt(out int result);
int index = result - 1;
bool isInRange = InputValidator.InRange(index, 0, _storage.Count);
if (isDigit == false || isInRange == false)
return;
Detail detail = _storage.RemoveAt(index);
string name = detail.Name;
if (car.CanRepair(name))
{
int additionalMoney = (int)Math.Round(detail.Price * _jobPriceFactor);
_wallet.Add(additionalMoney);
car.Repair();
Console.WriteLine($"\nCar repaired! You got +${additionalMoney}!\n");
}
else
{
Console.WriteLine("!!! Wrong detail, you will pay penalty. Car gone...");
Console.WriteLine($"-${_penalty}");
_wallet.Remove(_penalty);
}
}
public void Refuse()
{
Console.WriteLine("!!! You refused me, you should pay moral compensation!");
Console.WriteLine($"-${_penalty}");
_wallet.Remove(_penalty);
}
}
}
namespace WalletAssembly
{
class Wallet
{
private int _value;
public Wallet(int value)
{
_value = value;
}
public bool IsEmpty => _value <= 0;
public void Add(int amount)
{
_value += amount;
}
public void Remove(int amount)
{
_value -= amount;
}
public override string ToString()
{
return $"Wallet: ${_value}";
}
}
}
namespace StorageAssembly
{
class Storage
{
private readonly Dictionary<string, int> _details = new();
private List<Detail> _detailPrefabs;
public Storage(List<Detail> details, IEnumerable<Detail> detailPrefabs)
{
_detailPrefabs = new List<Detail>(detailPrefabs);
FillRandomAmount(details);
}
public int Count => _details.Count;
public void Add(string name, int amount = 1)
{
if (_details.ContainsKey(name))
{
_details[name] += amount;
}
else
{
_details[name] = amount;
}
}
public Detail RemoveAt(int index)
{
Detail detail = _detailPrefabs[index];
Remove(detail.Name);
return detail.Clone();
}
public void Remove(string name, int amount = 1)
{
if (_details.ContainsKey(name) == false)
throw new InvalidOperationException();
if (_details[name] < amount)
throw new ArgumentException(nameof(amount));
_details[name] -= amount;
if (_details[name] == 0)
_details.Remove(name);
}
public void Show()
{
int counter = 1;
Console.WriteLine($"Details in storage:");
foreach (var item in _details)
{
Console.WriteLine($"{counter}) {item.Key} (Count: {item.Value})");
counter++;
}
}
private void FillRandomAmount(IEnumerable<Detail> details)
{
int minAmount = 1;
int maxAmount = 10;
foreach (var detail in details)
{
string name = detail.Name;
int amount = Random.Shared.Next(minAmount, maxAmount);
Add(name, amount);
}
}
}
}
namespace DetailAssembly
{
class Detail
{
public Detail(string name, int price)
{
Name = name;
Price = price;
}
public string Name { get; }
public int Price { get; }
public bool IsBroken { get; private set; }
public void Repair()
{
IsBroken = false;
}
public void Break()
{
IsBroken = true;
}
public override string ToString()
{
return $"{Name} - ${Price}\t| Status: {(IsBroken ? "DAMAGED" : "OK")}";
}
public Detail Clone()
{
return new Detail(Name, Price);
}
}
class DetailFabric
{
private List<Detail> _detailPrefabs = new List<Detail>()
{
new Detail("Фары", 5),
new Detail("Мотор", 50),
new Detail("Тормоза", 20),
new Detail("Колесо_х4", 40),
};
public IEnumerable<Detail> DetailPrefabs => _detailPrefabs;
public List<Detail> CreateWithBroken()
{
List<Detail> details = Create();
int randomIndex = Random.Shared.Next(details.Count);
details[randomIndex].Break();
return details;
}
public List<Detail> Create()
{
List<Detail> details = new List<Detail>();
foreach (var detail in _detailPrefabs)
{
details.Add(detail.Clone());
}
return details;
}
}
}
namespace CarAssembly
{
class Car
{
private readonly List<Detail> _details;
public Car(List<Detail> details)
{
_details = new List<Detail>(details);
}
public bool CanRepair(string name)
{
if (TryFindBreakdown(out Detail brokenDetail) == false)
return false;
return name.Equals(brokenDetail.Name);
}
public void Repair()
{
if (TryFindBreakdown(out Detail brokenDetail))
{
brokenDetail.Repair();
}
}
private bool TryFindBreakdown(out Detail detail)
{
foreach (var item in _details)
{
if (item.IsBroken)
{
detail = item;
return true;
}
}
detail = null;
return false;
}
public override string ToString()
{
string details = string.Empty;
foreach (var detail in _details)
{
details += $"{detail}\n";
}
return details;
}
}
class CarFabric
{
private readonly DetailFabric _detailFabric;
public CarFabric(DetailFabric detailFabric)
{
_detailFabric = detailFabric;
}
public List<Car> Create(int amount)
{
List<Car> cars = new List<Car>(amount);
for (int i = 0; i < amount; i++)
{
List<Detail> details = _detailFabric.CreateWithBroken();
cars.Add(new Car(details));
}
return cars;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment