Last active
March 21, 2024 16:54
-
-
Save GigaOrts/3fdf3c24a19e903c13b5c1459208547b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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