-
-
Save StrikerXx798/65d5cba7883adf88c429cbcf84c1d033 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 System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
namespace ConsoleApp1 | |
{ | |
public class Program | |
{ | |
static void Main(string[] args) | |
{ | |
Console.InputEncoding = Encoding.Unicode; | |
Console.OutputEncoding = Encoding.Unicode; | |
AutoService service = new AutoService(); | |
service.Open(); | |
} | |
} | |
static class RandomUtils | |
{ | |
private static readonly Random s_random = new Random(); | |
private static readonly bool[] _boolVariants = { false, true }; | |
public static int Next(int minValue, int maxValue) | |
{ | |
return s_random.Next(minValue, maxValue); | |
} | |
public static bool NextBool() | |
{ | |
int index = s_random.Next(0, _boolVariants.Length); | |
return _boolVariants[index]; | |
} | |
} | |
class Detail | |
{ | |
public Detail(string name, int price, bool isBroken = false) | |
{ | |
Name = name; | |
Price = price; | |
IsBroken = isBroken; | |
} | |
public string Name { get; } | |
public int Price { get; } | |
public bool IsBroken { get; private set; } | |
public void Break() => IsBroken = true; | |
public void Repair() => IsBroken = false; | |
} | |
class DetailCell | |
{ | |
public DetailCell(Detail detail, int count) | |
{ | |
Detail = detail; | |
Count = count; | |
} | |
public Detail Detail { get; } | |
public int Count { get; private set; } | |
public void TakeOne() | |
{ | |
if (Count > 0) | |
Count--; | |
} | |
public void Add(int count) | |
{ | |
Count += count; | |
} | |
} | |
class DetailCreator | |
{ | |
private readonly List<Detail> _allDetails = new List<Detail> | |
{ | |
new Detail("Двигатель", 500), | |
new Detail("Тормоза", 200), | |
new Detail("Фара", 100), | |
new Detail("Колесо", 150), | |
new Detail("Аккумулятор", 250), | |
}; | |
public IEnumerable<Detail> GetAllDetails() | |
{ | |
foreach (var detail in _allDetails) | |
yield return new Detail(detail.Name, detail.Price); | |
} | |
} | |
class DetailWarehouse | |
{ | |
private List<DetailCell> _cells = new List<DetailCell>(); | |
private DetailCreator _detailCreator = new DetailCreator(); | |
public void AddDetail(string name, int count) | |
{ | |
var detail = _detailCreator.GetAllDetails().FirstOrDefault(x => x.Name == name); | |
if (detail == null) | |
return; | |
if (TryGetCell(name, out var cell)) | |
{ | |
cell.Add(count); | |
} | |
else | |
{ | |
_cells.Add(new DetailCell(detail, count)); | |
} | |
} | |
public bool HasDetail(string name) | |
{ | |
return TryGetCell(name, out var cell) && cell.Count > 0; | |
} | |
public bool TryTakeDetail(string name, out Detail takenDetail) | |
{ | |
takenDetail = null; | |
if (TryGetCell(name, out var cell) && cell.Count > 0) | |
{ | |
cell.TakeOne(); | |
takenDetail = new Detail(cell.Detail.Name, cell.Detail.Price); | |
return true; | |
} | |
return false; | |
} | |
private bool TryGetCell(string name, out DetailCell cell) | |
{ | |
cell = _cells.FirstOrDefault(c => c.Detail.Name == name); | |
return cell != null; | |
} | |
public void Show() | |
{ | |
Console.WriteLine("\nСклад деталей:"); | |
foreach (var cell in _cells) | |
{ | |
Console.WriteLine($"{cell.Detail.Name}: {cell.Count} шт. (Цена: {cell.Detail.Price} руб.)"); | |
} | |
} | |
public IEnumerable<Detail> GetAllWarehouseDetails() | |
{ | |
foreach (var cell in _cells) | |
{ | |
for (int i = 0; i < cell.Count; i++) | |
yield return new Detail(cell.Detail.Name, cell.Detail.Price); | |
} | |
} | |
} | |
class Car | |
{ | |
private List<Detail> _details; | |
public Car(string name, List<Detail> details) | |
{ | |
Name = name; | |
_details = details; | |
} | |
public string Name { get; } | |
public List<Detail> GetBrokenDetails() | |
{ | |
var brokenDetails = new List<Detail>(); | |
foreach (var detail in _details) | |
{ | |
if (detail.IsBroken) | |
brokenDetails.Add(detail); | |
} | |
return brokenDetails; | |
} | |
public void ShowDetails() | |
{ | |
foreach (var detail in _details) | |
{ | |
string status = detail.IsBroken ? "Сломана" : "Исправна"; | |
Console.WriteLine($"{detail.Name}: {status}"); | |
} | |
} | |
public bool IsFullyRepaired() | |
{ | |
foreach (var detail in _details) | |
{ | |
if (detail.IsBroken) | |
return false; | |
} | |
return true; | |
} | |
public void ReplaceDetailWithNew(Detail newDetail) | |
{ | |
for (int index = 0; index < _details.Count; index++) | |
{ | |
if (_details[index].Name == newDetail.Name && _details[index].IsBroken) | |
{ | |
_details[index] = newDetail; | |
break; | |
} | |
} | |
} | |
public IEnumerable<Detail> GetAllDetails() | |
{ | |
foreach (var detail in _details) | |
yield return detail; | |
} | |
} | |
class CarFactory | |
{ | |
private DetailCreator _detailCreator = new DetailCreator(); | |
public Car CreateRandom(string name) | |
{ | |
var details = new List<Detail>(); | |
foreach (var template in _detailCreator.GetAllDetails()) | |
{ | |
bool isBroken = RandomUtils.NextBool(); | |
details.Add(new Detail(template.Name, template.Price, isBroken)); | |
} | |
if (details.All(detail => detail.IsBroken == false)) | |
{ | |
int index = RandomUtils.Next(0, details.Count); | |
var broken = details[index]; | |
details[index] = new Detail(broken.Name, broken.Price, true); | |
} | |
return new Car(name, details); | |
} | |
} | |
class AutoService | |
{ | |
private const int StartBalance = 1000; | |
private const int PenaltyBeforeRepair = 100; | |
private const int PenaltyPerBrokenDetail = 50; | |
private const int RepairPriceDivider = 2; | |
private const int CommandShowCarQueue = 1; | |
private const int CommandShowWarehouse = 2; | |
private const int CommandRepairNextCar = 3; | |
private const int CommandExit = 0; | |
private const int CommandReplaceDetail = 1; | |
private const int CommandRefuseRepair = 2; | |
private const int CommandBack = 0; | |
private int _balance = StartBalance; | |
private DetailWarehouse _warehouse = new DetailWarehouse(); | |
private Queue<Car> _cars = new Queue<Car>(); | |
private DetailCreator _detailCreator = new DetailCreator(); | |
public AutoService() | |
{ | |
FillWarehouse(); | |
FillCarQueue(); | |
} | |
public void Open() | |
{ | |
bool isOpen = true; | |
while (isOpen) | |
{ | |
Console.WriteLine($"\nБаланс автосервиса: {_balance} руб."); | |
Console.WriteLine($"{CommandShowCarQueue} - Показать очередь машин"); | |
Console.WriteLine($"{CommandShowWarehouse} - Показать склад деталей"); | |
Console.WriteLine( | |
$"{CommandRepairNextCar} - Приступить к ремонту следующей машины" | |
); | |
Console.WriteLine($"{CommandExit} - Выйти"); | |
int command = GetNumberInput("Введите команду: "); | |
switch (command) | |
{ | |
case CommandShowCarQueue: | |
ShowCarQueue(); | |
break; | |
case CommandShowWarehouse: | |
_warehouse.Show(); | |
break; | |
case CommandRepairNextCar: | |
RepairNextCar(); | |
break; | |
case CommandExit: | |
isOpen = false; | |
break; | |
default: | |
Console.WriteLine("Неизвестная команда."); | |
break; | |
} | |
} | |
} | |
private void FillWarehouse() | |
{ | |
foreach (var detail in _detailCreator.GetAllDetails()) | |
_warehouse.AddDetail(detail.Name, 5); | |
} | |
private void FillCarQueue() | |
{ | |
var factory = new CarFactory(); | |
_cars.Enqueue(factory.CreateRandom("BMW X5")); | |
_cars.Enqueue(factory.CreateRandom("Lada Granta")); | |
_cars.Enqueue(factory.CreateRandom("Toyota Camry")); | |
_cars.Enqueue(factory.CreateRandom("Ford Focus")); | |
} | |
private void ShowCarQueue() | |
{ | |
if (_cars.Count == 0) | |
{ | |
Console.WriteLine("Очередь пуста."); | |
return; | |
} | |
int index = 1; | |
foreach (var car in _cars) | |
{ | |
Console.WriteLine($"{index}. {car.Name} (Поломок: {car.GetBrokenDetails().Count})"); | |
index++; | |
} | |
} | |
private void RepairNextCar() | |
{ | |
if (_cars.Count == 0) | |
{ | |
Console.WriteLine("Очередь пуста."); | |
return; | |
} | |
var car = _cars.Peek(); | |
Console.Clear(); | |
Console.WriteLine($"Ремонтируем: {car.Name}"); | |
bool isRepairing = true; | |
bool isStartedRepair = false; | |
var replacedDetails = new List<Detail>(); | |
while (isRepairing) | |
{ | |
Console.WriteLine("\nСостояние машины:"); | |
car.ShowDetails(); | |
if (car.IsFullyRepaired()) | |
{ | |
HandleFullyRepairedCar(car, replacedDetails); | |
isRepairing = false; | |
continue; | |
} | |
Console.WriteLine($"\n{CommandReplaceDetail} - Заменить деталь"); | |
Console.WriteLine($"{CommandRefuseRepair} - Отказаться от ремонта"); | |
Console.WriteLine($"{CommandBack} - Вернуться в меню"); | |
int command = GetNumberInput("Введите команду: "); | |
switch (command) | |
{ | |
case CommandReplaceDetail: | |
ReplaceDetail(car, replacedDetails); | |
isStartedRepair = true; | |
break; | |
case CommandRefuseRepair: | |
RefuseRepair(car, isStartedRepair); | |
isRepairing = false; | |
break; | |
case CommandBack: | |
isRepairing = false; | |
break; | |
default: | |
Console.WriteLine("Неизвестная команда."); | |
break; | |
} | |
} | |
} | |
private void HandleFullyRepairedCar(Car car, List<Detail> replacedDetails) | |
{ | |
Console.WriteLine("Машина полностью отремонтирована!"); | |
int reward = GetRepairRewardForReplaced(replacedDetails); | |
_balance += reward; | |
Console.WriteLine($"Вы получили {reward} руб. за ремонт."); | |
_cars.Dequeue(); | |
} | |
private void RefuseRepair(Car car, bool isStartedRepair) | |
{ | |
int penalty = isStartedRepair | |
? car.GetBrokenDetails().Count * PenaltyPerBrokenDetail | |
: PenaltyBeforeRepair; | |
_balance -= penalty; | |
Console.WriteLine($"Вы заплатили штраф {penalty} руб."); | |
_cars.Dequeue(); | |
} | |
private void ReplaceDetail(Car car, List<Detail> replacedDetails) | |
{ | |
var brokenDetails = car.GetBrokenDetails(); | |
if (brokenDetails.Count == 0) | |
{ | |
Console.WriteLine("Нет сломанных деталей."); | |
return; | |
} | |
Console.WriteLine("Сломанные детали:"); | |
for (int index = 0; index < brokenDetails.Count; index++) | |
Console.WriteLine($"{index + 1} - {brokenDetails[index].Name}"); | |
Console.WriteLine($"{CommandBack} - Назад"); | |
int input = GetNumberInput("Выберите деталь для замены: "); | |
if (input == CommandBack) | |
return; | |
if (input < 1 || input > brokenDetails.Count) | |
{ | |
Console.WriteLine("Некорректный выбор."); | |
return; | |
} | |
var detail = brokenDetails[input - 1]; | |
if (!_warehouse.HasDetail(detail.Name)) | |
{ | |
Console.WriteLine($"Деталь '{detail.Name}' отсутствует на складе."); | |
return; | |
} | |
if (_warehouse.TryTakeDetail(detail.Name, out Detail newDetail) == false) | |
{ | |
Console.WriteLine($"Деталь '{detail.Name}' отсутствует на складе или закончилась."); | |
return; | |
} | |
car.ReplaceDetailWithNew(newDetail); | |
replacedDetails.Add(newDetail); | |
_balance += newDetail.Price + GetRepairPrice(newDetail.Name); | |
Console.WriteLine( | |
$"Деталь '{newDetail.Name}' успешно заменена. Получено: {newDetail.Price + GetRepairPrice(newDetail.Name)} руб." | |
); | |
} | |
private int GetRepairRewardForReplaced(List<Detail> replacedDetails) | |
{ | |
int sum = 0; | |
foreach (var detail in replacedDetails) | |
sum += detail.Price + GetRepairPrice(detail.Name); | |
return sum; | |
} | |
private int GetRepairPrice(string name) | |
{ | |
return _detailCreator.GetAllDetails().FirstOrDefault(d => d.Name == name)?.Price | |
/ RepairPriceDivider | |
?? 0; | |
} | |
private int GetNumberInput(string message) | |
{ | |
Console.WriteLine(message); | |
string input = Console.ReadLine(); | |
int number; | |
while (int.TryParse(input, out number) == false) | |
{ | |
Console.WriteLine("Некорректный ввод. Попробуйте снова."); | |
input = Console.ReadLine(); | |
} | |
return number; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment