program ParkingApp;
{$mode objfpc}{$H+}
{$codepage UTF-8}
uses
heaptrc, // Поиск утечек памяти в куче
{$ifdef unix}cwstring,{$endif}
SysUtils,
ConsoleUtils,
Parking; // Наш модуль логики
{ Безопасный ввод чисел через паттерн TryStrToInt }
function ReadInteger(const APrompt: string): Integer;
var
S: string;
begin
repeat
Write(APrompt);
ReadLn(S);
if not TryStrToInt(S, Result) then
WriteLn(Format('Ошибка: "%s" — не число. Попробуйте ещё раз.', [S]));
until TryStrToInt(S, Result);
end;
var
ParkingLot: TParkingLot;
InitialCapacity: Integer;
MenuChoice: Integer;
License: string;
SpotNum: Integer;
begin
InitialCapacity := ReadInteger('Вместимость парковки: ');
ParkingLot := TParkingLot.Create(InitialCapacity);
// Глобальный try..finally защищает ОЗУ от утечек при аварийном выходе
try
WriteLn(Format('=== Парковка (%d места) ===', [ParkingLot.Capacity]));
WriteLn('1. Припарковать машину (автоматически)');
WriteLn('2. Припарковать на конкретное место');
WriteLn('3. Выехать');
WriteLn('4. Найти машину');
WriteLn('5. Переставить машину');
WriteLn('6. Показать статус парковки');
WriteLn('0. Выход');
repeat
MenuChoice := ReadInteger('> ');
// Внутренний try..except ловит кастомные ошибки парковки и гасит их
try
case MenuChoice of
1:
begin
Write('Номер машины: ');
ReadLn(License);
SpotNum := ParkingLot.Park(License);
WriteLn(Format('Машина припаркована на место %d.', [SpotNum]));
end;
2:
begin
Write('Номер машины: ');
ReadLn(License);
SpotNum := ReadInteger('Номер места: ');
ParkingLot.ParkAtSpot(SpotNum, License);
WriteLn(Format('Машина припаркована на место %d.', [SpotNum]));
end;
3:
begin
Write('Номер машины: ');
ReadLn(License);
SpotNum := ParkingLot.FindCar(License); // Узнаем место до удаления
ParkingLot.Leave(License);
WriteLn(Format('Место %d освобождено.', [SpotNum]));
end;
4:
begin
Write('Номер машины: ');
ReadLn(License);
SpotNum := ParkingLot.FindCar(License);
WriteLn(Format('Машина %s найдена на месте %d.', [License, SpotNum]));
end;
5:
begin
Write('Номер машины: ');
ReadLn(License);
SpotNum := ReadInteger('Новое место: ');
ParkingLot.MoveCar(License, SpotNum);
WriteLn(Format('Машина %s успешно перемещена на место %d.', [License, SpotNum]));
end;
6:
begin
ParkingLot.PrintStatus;
end;
0: WriteLn('До свидания!');
end;
except
on E: EParkingError do
WriteLn('Ошибка: ', E.Message, '.');
end;
until MenuChoice = 0;
finally
ParkingLot.Free; // Гарантированное уничтожение объекта и чистка памяти
end;
end.