Skip to content

Instantly share code, notes, and snippets.

@StrikerXx798
Last active June 21, 2025 17:16
Show Gist options
  • Save StrikerXx798/65d5cba7883adf88c429cbcf84c1d033 to your computer and use it in GitHub Desktop.
Save StrikerXx798/65d5cba7883adf88c429cbcf84c1d033 to your computer and use it in GitHub Desktop.
ДЗ: Автосервис
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