program Project1; {$mode objfpc}{$H+} {$codepage utf8} uses {$IFDEF UNIX} cthreads, {$ENDIF} Classes, SysUtils, CustApp { you can add units after this }; type StateType = (pay, coffee, cup, back); type CommandType = ( pay5, pay10, pay20, pay50, pay100, pay200, chooseblack, choosesugar, coosecappu, choosecacao, choosecup, choosenocup, payback ); type { TStateMachine } TStateMachine = class(TCustomApplication) protected procedure DoRun; override; public constructor Create(TheOwner: TComponent); override; destructor Destroy; override; function GetNextCommand: CommandType; end; { TStateMachine } procedure TStateMachine.DoRun; var ErrorMsg: String; State: StateType = pay; Command: CommandType; moneyPayed: Integer = 0; begin // quick check parameters ErrorMsg := CheckOptions('h', 'help'); if ErrorMsg <> '' then begin ShowException(Exception.Create(ErrorMsg)); Terminate; Exit; end; while true do begin Command := GetNextCommand; case State of pay: begin case Command of pay5: begin moneyPayed := moneyPayed + 5; end; pay10: begin moneyPayed := moneyPayed + 10; end; pay20: begin moneyPayed := moneyPayed + 20; end; pay50: begin moneyPayed := moneyPayed + 50; end; pay100: begin moneyPayed := moneyPayed + 100; end; pay200: begin moneyPayed := moneyPayed + 200; end; chooseblack, choosesugar, coosecappu, choosecacao: begin if moneyPayed >= 70 then begin State := coffee; end else begin WriteLn('Вы бросили недостаточно денег.'); end; end else WriteLn('Неверная команда!'); end; end; coffee: begin case Command of choosecup, choosenocup: begin State := cup; end; else WriteLn('Неверная команда!'); end; end; cup: begin case Command of payback: begin State := back; WriteLn('Ваша сдача: ' + IntToStr(moneyPayed - 70)); Break; end; else WriteLn('Неверная команда!'); end; end; back: begin end; end; end; // stop program loop Terminate; end; constructor TStateMachine.Create(TheOwner: TComponent); begin inherited Create(TheOwner); StopOnException:=True; end; destructor TStateMachine.Destroy; begin inherited Destroy; end; function TStateMachine.GetNextCommand: CommandType; var Input: String; begin Writeln('Введите команду:'); while true do begin Readln(Input); case Input of 'pay5': begin Result := pay5; Exit; end; 'pay10': begin Result := pay10; Exit; end; 'pay20': begin Result := pay20; Exit; end; 'pay50': begin Result := pay50; Exit; end; 'pay100': begin Result := pay100; Exit; end; 'pay200': begin Result := pay200; Exit; end; 'chooseblack': begin Result := chooseblack; Exit; end; 'choosesugar': begin Result := choosesugar; Exit; end; 'choosecappu': begin Result := coosecappu; Exit; end; 'choosecacao': begin Result := choosecacao; Exit; end; 'choosecup': begin Result := choosecup; Exit; end; 'choosenocup': begin Result := choosenocup; Exit; end; 'payback': begin Result := payback; Exit; end else Writeln('Команда не существует. Попробуйте еще раз:'); end; end; end; var Application: TStateMachine; begin Application:=TStateMachine.Create(nil); Application.Title:='State automat'; Application.Run; Application.Free; end.