Программирование турникета метро

    Содержание.

  1. Задание
  2. Описание диаграмм
    1. Диаграмма использования
    2. Диаграмма последовательности
    3. Диаграмма активности
    4. Диаграмма классов
  3. Описание классов
    1. Класс TCard
    2. Tprocessor
    3. Tform
  4. Руководство пользователя

 

2.Описание диаграмм

    1. Диаграмма вариантов использования

Описание.

Задачи  пассажира: 1. Вставить карту. 2. Ввести PIN код. 3. Пройти через турникет.

Задачи  блока управления: 1. Считать и  проверить карту. 2. Проверить введенный  пассажиром PIN код. 3. Снять деньги с карты. 4. Сохранить время получения средств в специальный файл. 5. Отправить сигнал на турникет о разрешении проезда. 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

2.2. Диаграмма последовательности

Описание.

Пассажир  вставляет карту. 2. Блок управления считывает параметры карты во внутреннюю память и проверяет необходимые  атрибуты. 3. Блок управления выдает приглашение  о вводе PIN кода на монитор. 4. Пассажир вводит код. 5. Блок управления проверяет код. 6. Блок управления снимает необходимую сумму с карты. 6. Блок управления посылает сигнал на турникет о разрешении прохода. 7. Карта возвращается пассажиру.

2.3.Диаграмма деятельности

Описание.

Блок  управления ожидает ввода карты. Если на турникете срабатывает датчик от прохода пассажира. На турникет посылается сигнал закрытия шлагбаума.

После ввода карты происходит ее проверка. Затем вводится PIN код. Далее снимается необходимая сумма с карты. Посылается сигнал на турникет об открытии турникета. После того как пассажир начинает движение (срабатывает датчик), начинается отсчет времени 5 сек. По окончании прохода, турникет возвращается в исходное состояние.

2.4.Диаграмма классов

Класс TProcessor  содержит переменную класса TCard и использует класс формы (монитора) для вывода сообщений и другой информации.

 
3.
Описание классов.

3.1 Класс TCard. 

fTypeOfCard тип integer. Содержит тип карты. Верный тип карты должен быть равен 3.

fPIN тип integer. Содержит PIN код. Состоит из 4-х цифр.

fDateLimit тип TDateTime. Содержит срок использования карты.

fBlocked тип Boolean. Содержит флаг блокировки карты.

fSumma тип integer. Сумма средств на счете владельца. 

    1. Класс TProcessor.

fTryCount тип integer. Содержит количество попыток. При превышении 3 карта будет заблокирована.

fCard тип TCard. Содержит переменную, в которой содержатся все данные текущей карты.

CheckPIN(PIN:integer). Функция проверки введенного кода (передается в переменной PIN). Если код верный возвращается TRUE, иначе FALSE.

LoadAndCheckCard(fFile:integer;FileName:string). Функция загрузки карты во внутреннюю переменную и проверка необходимых атрибутов. Возвращает TRUE если карту удалось загрузить и все показатели атрибутов в норме, иначе FALSE.

GetMoney(). Функция снимает деньги с карты, если операция прошла успешно возвращает TRUE. Если на карте недостаточно средств возвращает FALSE.

BlockCard(). Устанавливает в карте атрибут блокировки в TRUE и сохраняет. 

3.3. Класс TMainForm. (Класс главной формы/монитора) 

LabelNextAction: TLabel; - выводит подсказки о дальнейшем порядке действий пользователя.

LabelStop: TLabel; - выводит надпись «СТОП», которая указывает на запрет прохода.

LabelGo: TLabel; - выводит надпись «ПРООДИ», которая указывает на возможность прохода.

LabelTimer: TLabel; - выводит количество оставшегося времени до закрытия турникета.

Timer1: TTimer; - объект, который отсчитывает время для прохода пассажира .

LabelMessage: TLabel; - выводит предупреждения и сообщения об ошибках карты или ввода данных.

procedure Timer1Timer(Sender: TObject); Процедура отсчитывает время разрешенное для прохода и по окончании переводит турникет в начальное состояние («Закрыт»).

 

    4.Руководство пользователя.

1. При нажатии на кнопку «Вставить карту», появляется стандартное диалоговое окно открытия файла. Выбираем нужный файл с картой.

2. На мониторе выдается приглашение «Введите PIN код». 
 
 
 
 
 
 
 
 
 
 
 
 

3. С помощью клавиатуры на форме вводим PIN код (4 цифры) и нажимаем Enter. Если код неправильный будет выдано предупреждение «Неверный PIN». После чего дается еще две попытки ввода, в противном случае карта будет заблокирована и программа вернется в исходное состояние. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

4.Если PIN код правильный загорается зеленая надпись «Проходи».Нажимаем кнопку пройти.

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

5.После того время истечет программа вернется в исходное состояние.

 

В меню Файл-> Редактор карт находится редактор карт.

В появившемся  окне вводим тип карты (верный тип 3), PIN код, сумму на карте (не менее 50) и срок действия карты. Далее нажимаем сохранить и вводим имя файла.

Также с помощью  редактора можно изменять данные уже созданных карт (добавлять  средства, снимать блокировку, увеличивать срок или менять PIN код).

 

Листинг программы.

unit Unit1;

interface

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, StdCtrls, ActnList, Menus, ExtCtrls;

type

  TMainForm = class(TForm)

    ButtonLoadCard: TButton;

    MainMenu1: TMainMenu;

    ActionList1: TActionList;

    OpenDialog1: TOpenDialog;

    LabelNextAction: TLabel;

    Button1: TButton;

    Button2: TButton;

    Button3: TButton;

    Button4: TButton;

    Button5: TButton;

    Button6: TButton;

    Button7: TButton;

    Button8: TButton;

    Button9: TButton;

    Button0: TButton;

    ButtonBackSpace: TButton;

    ButtonEnter: TButton;

    mFile: TMenuItem;

    mCreateCard: TMenuItem;

    LabelStop: TLabel;

    LabelGo: TLabel;

    LabelTimer: TLabel;

    Timer1: TTimer;

    ButtonMove: TButton;

    ImageCar: TImage;

    TimerMove: TTimer;

    ShapeBlock: TShape;

    Shape2: TShape;

    ShapeSensor1: TShape;

    LabelMessage: TLabel;

    Bevel1: TBevel;

    procedure ButtonLoadCardClick(Sender: TObject);

    procedure Button1Click(Sender: TObject);

    procedure Button2Click(Sender: TObject);

    procedure Button3Click(Sender: TObject);

    procedure Button4Click(Sender: TObject);

    procedure Button5Click(Sender: TObject);

    procedure Button6Click(Sender: TObject);

    procedure Button7Click(Sender: TObject);

    procedure Button8Click(Sender: TObject);

    procedure Button9Click(Sender: TObject);

    procedure Button0Click(Sender: TObject);

    procedure ButtonBackSpaceClick(Sender: TObject);

    procedure ChangeKeybordEnabled(Flag: boolean);

    procedure FormCreate(Sender: TObject);

    procedure mCreateCardClick(Sender: TObject);

    procedure ButtonEnterClick(Sender: TObject);

    procedure Timer1Timer(Sender: TObject);

    procedure TimerMoveTimer(Sender: TObject);

    procedure ButtonMoveClick(Sender: TObject);

  private

    { Private declarations }

  public

    { Public declarations }

  end; 

  procedure EnterNumber(Number:String);

var

  MainForm: TMainForm; 

implementation

Uses Unit2,Unit3;

{$R *.dfm}

var

  glCard:TCard;

  glTryCount:integer;

  Proc:TProcessor; 

procedure TMainForm.ChangeKeybordEnabled(Flag: boolean);

begin

  Button1.Enabled         := Flag;

  Button2.Enabled         := Flag;

  Button3.Enabled         := Flag;

  Button4.Enabled         := Flag;

  Button5.Enabled         := Flag;

  Button6.Enabled         := Flag;

  Button7.Enabled         := Flag;

  Button8.Enabled         := Flag;

  Button9.Enabled         := Flag;

  Button0.Enabled         := Flag;

  ButtonBackSpace.Enabled := Flag;

  ButtonEnter.Enabled     := Flag;

  if Flag then

  begin

    ButtonLoadCard.Caption  := 'Достать карту';

    LabelNextAction.Caption := 'Введите PIN код';

    LabelMessage.Caption := '';

  end

  else

  begin

    ButtonLoadCard.Caption  := 'Вставить карту';

    LabelNextAction.Caption := 'Вставьте карту';

    glCard.Free;

    LabelStop.Font.Color := clRed;

    LabelGo.Font.Color := clInactiveBorder;

    LabelTimer.Caption := '';

  end;

end;

procedure TMainForm.FormCreate(Sender: TObject);

begin

  ChangeKeybordEnabled(False);

end;

procedure TMainForm.mCreateCardClick(Sender: TObject);

begin

  FormEditCard := TformEditCard.Create(Application);

  FormEditCard.ShowModal();

  FormEditCard.Free;

end;

procedure TMainForm.Timer1Timer(Sender: TObject);

var i:integer;

begin

  i := StrToInt(LabelTimer.Caption)-1;

  LabelTimer.Caption := IntToStr(i);

  if i=0 then

  begin

    ChangeKeybordEnabled(false);

    Timer1.Enabled := false;

    ImageCar.Top := 189;

  end;

   

end;

procedure TMainForm.TimerMoveTimer(Sender: TObject);

var iTop:integer;

begin

iTop := ImageCar.Top;

if iTop <-40 then

begin

   TimerMove.Enabled := false;

   exit;

end;

if ShapeBlock.Visible then

   if iTop <(ShapeBlock.Top + ShapeBlock.Height*2) then

   begin

     TimerMove.Enabled := false;

     exit;

   end;

if iTop=(ShapeSensor1.Top+ShapeSensor1.Height) then

   if LabelGo.Font.Color = clInactiveBorder then

   begin

     ShapeBlock.Visible := true;

     windows.Beep(1000,100);

   end;

if iTop<(ShapeSensor1.Top+ShapeSensor1.Height) then

   if LabelGo.Font.Color <> clInactiveBorder then

     Timer1.Enabled := true;

ImageCar.Top := iTop - 1;

end;

procedure EnterNumber(Number:String);

var Str:String;

begin

  Str := MainForm.LabelNextAction.Caption;

  if Length(Str) = 4 then

    exit;

  if (Str = 'Введите PIN код')

  or (Str = 'Неверный PIN!') then

    Str := '';

  MainForm.LabelNextAction.Caption := Str + Number;

end;

procedure TMainForm.Button0Click(Sender: TObject);

begin

  EnterNumber('0');

end;

procedure TMainForm.Button1Click(Sender: TObject);

begin

  EnterNumber('1');

end;

procedure TMainForm.Button2Click(Sender: TObject);

begin

  EnterNumber('2');

end;

procedure TMainForm.Button3Click(Sender: TObject);

begin

  EnterNumber('3');

end;

procedure TMainForm.Button4Click(Sender: TObject);

begin

  EnterNumber('4');

end;

procedure TMainForm.Button5Click(Sender: TObject);

begin

  EnterNumber('5');

end;

procedure TMainForm.Button6Click(Sender: TObject);

begin

  EnterNumber('6');

end;

procedure TMainForm.Button7Click(Sender: TObject);

begin

  EnterNumber('7');

end; 

procedure TMainForm.Button8Click(Sender: TObject);

begin

  EnterNumber('8');

end;

procedure TMainForm.Button9Click(Sender: TObject);

begin

  EnterNumber('9');

end;

procedure TMainForm.ButtonBackSpaceClick(Sender: TObject);

var Str:String;

begin

  Str := LabelNextAction.Caption;

  if Str = 'Введите PIN код'then

    exit;

  Delete(Str,Length(Str),1);

  if Str = '' then

    Str := 'Введите PIN код';

  LabelNextAction.Caption := Str;

end;

procedure TMainForm.ButtonEnterClick(Sender: TObject);

var

  FileHandle:integer;

  Pbool:boolean;

  tf:TextFile;

begin

  if (LabelNextAction.Caption = 'Введите PIN код')

  or (LabelNextAction.Caption = 'Неверный PIN!') then

    exit;

  if NOT Proc.CheckPIN(StrToInt(LabelNextAction.Caption)) then

  begin

    LabelNextAction.Caption := 'Неверный PIN!';

    if Proc.BlockCard() then

      ChangeKeybordEnabled(False);

    exit;

  end;

  if NOT Proc.GetMoney() then

  begin

    LabelMessage.Caption := 'На карте недостаточно средств!';

    ChangeKeybordEnabled(False);

    exit;

  end;

  LabelStop.Font.Color := clInactiveBorder;

  LabelGo.Font.Color   := clGreen;

  LabelTimer.Caption := '15';

  ShapeBlock.Visible := false;

  try

    AssignFile(tf,'C:\ProgramLog.txt');

    if FileExists('C:\ProgramLog.txt') = False then

       Rewrite(tf)

    else

     begin

       Append(tf);

     end;

    WriteLn(tf,TimeToStr(Time()));

  finally

    CloseFile(tf);

  end;

 

end;

procedure TMainForm.ButtonLoadCardClick(Sender: TObject);

var

  FileHandle:integer;

  fMessage:String;

begin

  if ButtonLoadCard.Caption = 'Достать карту' then

    begin

      ChangeKeybordEnabled(False);

      exit;

    end;

  if OpenDialog1.Execute then

  try

    FileHandle := FileOpen(OpenDialog1.FileName,fmOpenRead);

    Proc := TProcessor.Create;

    fMessage := Proc.LoadAndCheckCard(FileHandle,OpenDialog1.FileName);

    if fMessage ='OK' then

      ChangeKeybordEnabled(True)

    else

      LabelMessage.Caption := fMessage;

  finally

    FileClose(FileHandle);

  end; 

end;

procedure TMainForm.ButtonMoveClick(Sender: TObject);

begin

  TimerMove.Enabled := true;

end;

end.

 

unit Unit2; 

interface 

uses

  SysUtils, Dialogs; 

type

TCard = class(TObject)

  fTypeOfCard:integer;

  fPIN:integer;

  fSumma:integer;

  fBlocked:boolean;

  fDateLimit:TDateTime;

 

//published

end; 

type

TProcessor = class(TObject)

  fTryCount:integer;

  fCard:TCard;

  fFileName:String;

  function CheckPIN(PIN:integer):Boolean;

  function LoadAndCheckCard(fFile:integer;FileName:string): String;

  function GetMoney():Boolean;

  function BlockCard():Boolean;

  //procedure EnableTrip();

end; 

implementation 

function TProcessor.CheckPIN(PIN:integer):Boolean;

begin

  if PIN <> fCard.fPIN then

    Result := FALSE

  else

    Result := TRUE;

end; 

function TProcessor.LoadAndCheckCard(fFile:integer;FileName:string):String;

var

  FileHandle:integer;

  TypeOfCard:integer;

  d:TDateTime;

  Pbool:Boolean;

  PIN, Summa:integer;

begin

  fTryCount := 0;

  fFileName := FileName;

    FileHandle := fFile;

    FileRead(FileHandle,TypeOfCard,SizeOf(integer));

    fCard := TCard.Create;

    if TypeOfCard <> 3 then

    begin

      fCard.Free;

      Result := 'Неверный тип карты!';

      exit;

    end;

    fCard.fTypeOfCard := TypeOfCard;

    FileRead(FileHandle,d,SizeOf(TdateTime));

    if d < Date() then

    begin

      fCard.Free;

      Result := 'Карта просрочена!';

      exit;

    end;

    fCard.fDateLimit := d;

    FileRead(FileHandle,Pbool,SizeOf(boolean));

    if Pbool then

    begin

      fCard.Free;

      Result := 'Карта заблокирована!';

      exit;

    end;

    fCard.fBlocked := Pbool;

    FileRead(FileHandle,PIN,SizeOf(integer));

    fCard.fPIN := PIN;

    FileRead(FileHandle,Summa,SizeOf(integer));

    fCard.fSumma := Summa;

    Result := 'OK';

end; 

function TProcessor.GetMoney():Boolean;

var FileHandle,Summa:integer;

begin

  if fCard.fSumma < 50 then

    Result := FALSE

  else

  begin

    FileHandle := FileOpen(fFileName,fmOpenReadWrite);

    FileSeek(FileHandle,SizeOf(integer)+SizeOf(TDateTime)

    +SizeOf(boolean)+SizeOf(integer),0);

    Summa := fCard.fSumma - 50;

    FileWrite(FileHandle,Summa,SizeOf(integer));

    FileClose(FileHandle);

    Result := True;

  end;

end; 

function TProcessor.BlockCard():Boolean;

var FileHandle:integer;

PBool:Boolean;

begin

  if fTryCount >= 2 then

    begin

      FileHandle := FileOpen(fFileName,fmOpenReadWrite);

      FileSeek(FileHandle,SizeOf(integer)+SizeOf(TDateTime),0);

      Pbool := True;

      FileWrite(FileHandle,Pbool,SizeOf(boolean));

      FileClose(FileHandle);

      Result := true

    end

  else

  begin

    fTryCount := fTryCount+1;

    Result := false;

  end;

end;

end.

 

unit Unit3; 

interface 

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, StdCtrls, ComCtrls, ExtCtrls; 

type

  TFormEditCard = class(TForm)

    LabeledEditTypeOfCard: TLabeledEdit;

    LabeledEditPIN: TLabeledEdit;

    LabeledEditSumma: TLabeledEdit;

    CheckBoxBlocked: TCheckBox;

    DateTimePickerDateLimit: TDateTimePicker;

    ButtonOpen: TButton;

    ButtonSave: TButton;

    OpenDialog1: TOpenDialog;

    SaveDialog1: TSaveDialog;

    procedure ButtonSaveClick(Sender: TObject);

    procedure ButtonOpenClick(Sender: TObject);

  private

    { Private declarations }

  public

    { Public declarations }

  end; 

var

  FormEditCard: TFormEditCard; 

implementation 

Uses Unit2;

{$R *.dfm} 

procedure TFormEditCard.ButtonOpenClick(Sender: TObject);

var FileHandle:integer;

TypeOfCard,PIN,Summa:integer;

Pbool:boolean;

Pdate:TDateTime;

Card:TCard;

begin

if OpenDialog1.Execute then

begin

  try

    FileHandle := FileOpen(OpenDialog1.FileName,fmOpenRead);

    Card := Tcard.Create;

    FileRead(FileHandle,TypeOfCard,SizeOf(integer));

    Card.fTypeOfCard := TypeOfCard;

    FileRead(FileHandle,Pdate,SizeOf(TdateTime));

    Card.fDateLimit := Pdate;

    FileRead(FileHandle,Pbool,SizeOf(boolean));

    Card.fBlocked := Pbool;

    FileRead(FileHandle,PIN,SizeOf(integer));

    Card.fPIN := PIN;

    FileRead(FileHandle,Summa,SizeOf(integer));

    Card.fSumma := Summa;

    FileClose(FileHandle);

  except

    ShowMessage('Не  удалось открыть файл!');

    exit;

  end;

  LabeledEditTypeOfCard.Text       := IntToStr(Card.fTypeOfCard);

  LabeledEditPIN.Text              := IntToStr(Card.fPIN);

  LabeledEditSumma.Text            := IntToStr(Card.fSumma);

  CheckBoxBlocked.Checked          := Card.fBlocked;

  DateTimePickerDateLimit.DateTime := Card.fDateLimit;

end;

end; 

procedure TFormEditCard.ButtonSaveClick(Sender: TObject);

var FileHandle:integer;

Card:TCard;

begin

if SaveDialog1.Execute then

begin

  Card := TCard.Create;

  Card.fTypeOfCard := StrToInt(LabeledEditTypeOfCard.Text);

  Card.fPIN       := StrToInt(LabeledEditPIN.Text);

  Card.fSumma     := StrToInt(LabeledEditSumma.Text);

  Card.fBlocked   := CheckBoxBlocked.Checked;

  Card.fDateLimit := DateTimePickerDateLimit.DateTime;

  FileHandle := FileCreate(SaveDialog1.FileName);

  FileWrite(FileHandle,Card.fTypeOfCard,SizeOf(integer));

  FileWrite(FileHandle,Card.fDateLimit,SizeOf(TDateTime));

  FileWrite(FileHandle,Card.fBlocked,SizeOf(boolean));

  FileWrite(FileHandle,Card.fPIN,SizeOf(integer));

  FileWrite(FileHandle,Card.fSumma,SizeOf(integer));

  FileClose(FileHandle);

end;

end;

end.

  1. Задание.

    Вариант 16. Турникет метро  


Программирование турникета метро