Recent

Author Topic: I am the new of pascal .please give me some HELP!  (Read 20551 times)

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: I am the new of pascal .please give me some HELP!
« Reply #30 on: October 10, 2016, 06:19:42 pm »
And yet another crash in update_airtrafficfile, because count2 = 21....

Bart

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: I am the new of pascal .please give me some HELP!
« Reply #31 on: October 10, 2016, 07:06:22 pm »
About generation airplane number:
The Arrays are not necessary.
This will do nicely.

Code: [Select]
  z := '';
  for count :=  1 to 2 do z := z + chr(random(26)+65);
  for count := 1 to 7 do z := z + chr(random(10)+48);

Bart

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: I am the new of pascal .please give me some HELP!
« Reply #32 on: October 10, 2016, 07:11:29 pm »
@Bart:
afaik the idea is that the program is reading data from two files (i have adjusted my version to create them if not present).

One file's data represent an airport with plane numbers and their 'time-out'. The other file is 'the air' where planes can fly around.
In the latter file also plane number and 'time-out' value.

The program stores these data into arrays and then randomly (and also based on time-out) decides what the planes are going to do
- land on airpoirt
- departure from airport

At the same time, new planes are 'flying' in randomly.

The prorgram asks for permission if a plane is allowed to land or not. In case not it sets an new timeout value and processes the queue accordingly to time out values.

The best i can do for the moment as i'm a little busy atm.
Code: Pascal  [Select][+][-]
  1. Program air_traffic_control;
  2.  
  3. {$RANGECHECKS ON}{$OVERFLOWCHECKS ON}{$HINTS ON}
  4.  
  5. Uses
  6.   Dos, Crt, SysUtils, Classes;
  7.  
  8. const
  9.   DefaultPW              = '';
  10.   SystemInstructionDelay = 5000;
  11.   airtrafficfilename     = 'airtraffic.txt';
  12.   platformfilename       = 'airport_condition.txt';
  13.  
  14.  
  15. Type
  16.   Tairport_platform =
  17.   Record
  18.     airplane_no                  : string[30];
  19.     airplane_predicted_time_left : integer;
  20.   End;
  21.  
  22.   Tairtraffic_condition =
  23.   Record
  24.     airplane_no                  : string[30];
  25.     airplane_landing_time_left   : integer;
  26.   End;
  27.  
  28.  
  29. Var
  30.   hour                 : word = 0;
  31.   min                  : word = 0;
  32.   sec                  : word = 0;
  33.   msec                 : word = 0;
  34.   NumberOfLandedPlanes : integer = 0;
  35.   target               : integer = 0;
  36.   count,
  37.   count2,
  38.   z                    : integer;
  39.   platformfile,
  40.   airtrafficfile       : text;
  41.   platform             : array[1..30] of Tairport_platform;
  42.   airtraffic           : array[1..20] of Tairtraffic_condition;
  43.   ch                   : char;
  44.  
  45.  
  46. Procedure user_display;
  47. type
  48.   TDayType = (Sun,Mon,Tue,Wed,Thu,Fri,Sat);
  49. var
  50.   YY        : Word = 0;
  51.   MM        : word = 0;
  52.   DD        : word = 0;
  53.   DayOfWeek : Word = 0;
  54.   hour      : Word = 0;
  55.   min       : Word = 0;
  56.   sec       : Word = 0;
  57.   msec      : Word = 0;
  58.   today     : TDayType;
  59.   password  : string[20];
  60. begin
  61.   textbackground(black);
  62.   ClrScr;
  63.   Getdate(YY,MM,DD,DayOfWeek);
  64.   GetTime(hour,min,sec,msec);
  65.   Today := TDayType(DayOfWeek);
  66.   textcolor(yellow);
  67.   writeln('Welcome to execute air traffic control');
  68.  
  69.   repeat
  70.     textcolor(yellow);
  71.     write('Password:');
  72.     readln(password);
  73.     if password<>DefaultPW
  74.     then writeln('Wrong password,enter again');
  75.   until password=DefaultPW;
  76.  
  77.   ClrScr;
  78.   writeln('Day of Today:',DD,'/',MM,'/',YY,',',Today);
  79.   writeln('Current time: ',hour,':',min,':',sec);
  80.   writeln('Now start the system of air traffic control management');
  81.   repeat
  82.     textcolor(yellow);
  83.     write('Enter password again to continue:');
  84.     readln(password);
  85.     if password<>DefaultPW
  86.     then writeln('Wrong password,enter again');
  87.   until password=DefaultPW;
  88.   ClrScr;
  89. end;
  90.  
  91.  
  92. Procedure input_airtraffic(Var count2:integer);
  93. var n: integer;
  94. Begin
  95.   for n:= Low(airtraffic) to High(airtraffic)
  96.     do airtraffic[n].airplane_no := '';
  97.  
  98.   count2 := 0;
  99.   assign(airtrafficfile, airtrafficfilename);
  100.   reset(airtrafficfile);
  101.  
  102.   while not eof(airtrafficfile) do
  103.   begin
  104.     count2 := count2 + 1;
  105.     with airtraffic[count2] do
  106.     begin
  107.       readln(airtrafficfile,airplane_no);
  108.       readln(airtrafficfile,airplane_landing_time_left);
  109.     end;
  110.   end;
  111.  
  112.   close(airtrafficfile);
  113. End;
  114.  
  115.  
  116. procedure input_platform_condition(var num:integer);
  117. var
  118.   idx, n                       : integer;
  119.   airplane_no                  : String[30] = '';
  120.   airplane_predicted_time_left : integer    = 0;
  121. begin
  122.   Writeln('dumping airport plane stats');
  123.   num :=0;
  124.   for n := Low(platform) to High(platform)
  125.     do platform[n].airplane_no := '';
  126.  
  127.   assign(platformfile, platformfilename);
  128.   reset(platformfile);
  129.  
  130.   idx := 0;
  131.   while not eof(platformfile) do
  132.   begin
  133.     if (idx < High(platform)) then inc(idx) else break;
  134.  
  135.     with platform[idx] do
  136.     begin
  137.       readln(platformfile,airplane_no);
  138.       readln(platformfile,airplane_predicted_time_left);
  139.  
  140.       if (airplane_no <> '') then
  141.       begin
  142.         num := num + 1;
  143.         Writeln('[ok] Plane = ', airplane_no, ' predicted_time_left = ', airplane_predicted_time_left);
  144.       end
  145.       else
  146.         Writeln('[xx] Plane = ', airplane_no, ' predicted_time_left = ', airplane_predicted_time_left);
  147.     end;
  148.   end;
  149.   close(platformfile);
  150.  
  151.   WriteLn('Press enter to continue'); ReadLn;
  152. end;
  153.  
  154.  
  155. Procedure take_off(Var num,target:integer);
  156. Var
  157.   choice: char;
  158.   password: string[30];
  159. Begin
  160.   With platform[target] Do
  161.     Begin
  162.       Repeat
  163.         write('plane ',airplane_no,'is ready to take off,asking for permission(Y/N)?');
  164.         readln(choice);
  165.         If Not(choice In ['Y','y','N','n'])
  166.           Then write('Wrong input choice,please input choice again(Y/N):');
  167.         ClrScr;
  168.       Until (choice='y') Or (choice='Y') Or (choice='N') Or (choice='n');
  169.       If  (choice='N') Or (choice='n')
  170.         Then airplane_predicted_time_left := 5
  171.       Else
  172.         Begin
  173.           Repeat
  174.             write('Enter password to execute this order:');
  175.             readln(password);
  176.             ClrScr;
  177.           Until password=DefaultPW;
  178.           writeln('please wait for the processing of taking off.......');
  179.           delay(20000);
  180.           writeln('plane ',airplane_no,'has been taken off');
  181.           readln;
  182.           num := num-1;
  183.           airplane_no := '$$$';
  184.           airplane_predicted_time_left := 999;
  185.  
  186.         End;
  187.     End;
  188. End;
  189.  
  190.  
  191. procedure update_platform_time_left(Var num,target,count:integer);
  192. begin
  193.   target := 0;
  194.   if count <= High(platform) then
  195.   begin
  196.     count := count+1;
  197.     with platform[count] do
  198.     begin
  199.       airplane_predicted_time_left := airplane_predicted_time_left-1;
  200.       if (airplane_predicted_time_left<=0) and (airplane_no <> '') then
  201.       begin
  202.         target := count;
  203.         if (platform[target].airplane_no <> '$$$') then take_off(num,target);
  204.         if (count <= High(platform))
  205.         then update_platform_time_left(num,target,count);
  206.       end
  207.       else if count < High(platform)
  208.            then update_platform_time_left(num, target, count);
  209.     end;
  210.   end;
  211. end;
  212.  
  213.  
  214. Procedure update_air_traffic(count:integer;Var num,count2:integer);
  215. Var
  216.   choice1: char;
  217.   target,count1, n: integer;
  218.   password: string[10];
  219. Begin
  220.   n := 1;
  221.   target := 0;
  222.   count1 := 0;
  223.   count := count+1;
  224.  
  225.   If count<=count2 then
  226.   Begin
  227.     With airtraffic[count] Do
  228.     Begin
  229.       airplane_landing_time_left := airplane_landing_time_left-1;
  230.       If (airplane_landing_time_left<=0) And (airplane_no<>'') Then
  231.       Begin
  232.         Repeat
  233.           write('airplane ',airplane_no,' is asking for the permission of landing(Y/N):');
  234.           readln(choice1);
  235.         Until (choice1='y') Or (choice1='Y') Or (choice1='n') Or (choice1='N');
  236.         Repeat
  237.           write('Please input password to continue:');
  238.           readln(password);
  239.           ClrScr;
  240.         Until password=DefaultPW;
  241.  
  242.         Case choice1 Of
  243.           'y','Y':
  244.           Begin
  245.             Writeln('chosen to allow landing, searching for a free platform');
  246.  
  247.             Target := -1;
  248.             for count1 := 1 to Length(platform) do
  249.             begin
  250.               if platform[count1].airplane_no = '' then
  251.               begin
  252.                 target := count1;
  253.                 break;
  254.               end;
  255.             end;
  256.  
  257.             WriteLn('The target platform is ', target);
  258.             WriteLn('The value of count1 is ', count1);
  259.  
  260.             if target < 1 then
  261.             Begin
  262.               writeln('No platform remain, please stay on the air');
  263.               airplane_landing_time_left := 5;
  264.             end
  265.             else
  266.             begin
  267.               write('airplane ',airplane_no, ' landing to platform ',target);
  268.               readln;
  269.               platform[target].airplane_no := airplane_no;
  270.               platform[target].airplane_predicted_time_left := 400;
  271.               airplane_no := '';
  272.               num := num+1;
  273.               For n:=1 To (count2-1) Do
  274.               Begin
  275.                 If airtraffic[n].airplane_no<>'' Then
  276.                 Begin
  277. {???}             airtraffic[n].airplane_landing_time_left := airtraffic[n].airplane_landing_time_left;
  278.                 End;
  279.               End;
  280.             End;
  281.             count2 := count2-1;
  282.           End;
  283.           'n','N': airplane_landing_time_left := 5
  284.         End  { case choice }
  285.       End
  286.  
  287.       Else
  288.  
  289. //      if count <= High(airtraffic) then
  290.       if count < High(airtraffic) then
  291.       begin
  292.         update_air_traffic(count,num,count2);
  293.       end;
  294.     end;
  295.   end;
  296. end;
  297.  
  298.  
  299. Procedure generate_airplane_no(Var count2:integer);
  300. Var
  301.   x: array[1..3] Of char;
  302.   y: array[1..7] Of char;
  303.   z: string[30] = '';
  304.   count,abc: integer;
  305. Begin
  306. // ????
  307.   If count2< 30 Then
  308.   Begin
  309.     count2 := count2+1;
  310.     for count:= Low(x) to High(x)
  311.       do x[count] := ' ';
  312.     for count:= Low(y) to High(y)
  313.       do y[count] := ' ';
  314.  
  315.     if count2 <= High(airtraffic) then
  316.     begin
  317.       randomize;
  318.       abc := random(9);
  319.       for count:= Low(x) to High(x)
  320.         do x[count] := chr(random(26)+65);
  321.       for count:= Low(y) to High(y)
  322.         do y[count] := chr(random(10)+48);
  323.       for count := 1 To 2
  324.         do z := concat(z, x[count]);
  325.       for count := low(y) to High(y)
  326.         do z := concat(z, y[count]);
  327.  
  328.       with airtraffic[count2] do
  329.       begin
  330.         airplane_no := z;
  331.         airplane_landing_time_left := random(20)+ 1;  // ??? High(airtraffic) ?
  332.         readln;
  333.       end;
  334.     end;
  335.   end;
  336. end;
  337.  
  338.  
  339. Procedure update_platformfile;
  340. var
  341.   n: integer;
  342. begin
  343.   rewrite(platformfile);
  344.   for n := Low(PlatForm) to High(Platform) do
  345.   begin
  346.     with platform[n] do
  347.     begin
  348.       writeln(platformfile,airplane_no);
  349.       writeln(platformfile,airplane_predicted_time_left);
  350.     end;
  351.   end;
  352.   close(platformfile);
  353. end;
  354.  
  355.  
  356. Procedure update_airtrafficfile(Var count2:integer);
  357. Var n: integer;
  358. Begin
  359.   rewrite(airtrafficfile);
  360.   For n:=1 To count2 Do
  361.   Begin
  362.     With airtraffic[n] Do
  363.     Begin
  364.       writeln(airtrafficfile,airplane_no);
  365.       writeln(airtrafficfile,airplane_landing_time_left);
  366.     End;
  367.   End;
  368.   close(airtrafficfile);
  369. End;
  370.  
  371.  
  372. Begin
  373.   if not fileexists(airtrafficfilename) then
  374.   begin
  375.     with TStringList.Create do
  376.     begin
  377.       Append('fes2135487');
  378.       Append('3');
  379.       Append('qwe7634153');
  380.       Append('7');
  381.       Append('jfd1325748');
  382.       Append('11');
  383.       SaveToFile(airtrafficfilename);
  384.       Free;
  385.     end;
  386.   end;
  387.  
  388.   if not fileexists(platformfilename) then
  389.   begin
  390.     with TStringList.Create do
  391.     begin
  392.       SaveToFile(platformfilename);
  393.       Free;
  394.     end;
  395.   end;
  396.  
  397.   count2 := 0;
  398.   user_display;
  399.   input_airtraffic(count2);
  400.   input_platform_condition(NumberOfLandedPlanes);
  401.  
  402.   While NumberOfLandedPlanes>=0 Do
  403.   Begin
  404.     ClrScr;
  405.     GetTime(hour,min,sec,msec);
  406.     writeln('Current time: ',hour,':',min,':',sec);
  407.     z := 0;
  408.     writeln('There are total ',NumberOfLandedPlanes,' planes in the airport now');
  409.     writeln('There are total ',count2,' planes are waiting  for landing');
  410.     count := 0;
  411.     Repeat
  412.       writeln('Press Enter to continue/Press ESC to exit');
  413.       ch := ReadKey;
  414.       ClrScr;
  415.     Until (ch=#27) Or (ch=#13);
  416.  
  417.     Case ch Of
  418.       #13:
  419.       Begin
  420.         if ( (NumberOfLandedPlanes=0) and (count2=0) ) then
  421.         Begin
  422.           writeln('No plane information found, please wait until plane land/take off....');
  423.           writeln('press ENTER to continue!!');
  424.           Repeat
  425.             ch := ReadKey;
  426.           Until (ch=#13);
  427.           ClrScr;
  428. //      End;
  429. //      If (num<>0) And (count2<>0) Then
  430.         end
  431.         else
  432.         Begin
  433.           generate_airplane_no(count2);
  434.           ClrScr;
  435.           writeln('Waiting for the system instruction.....');
  436.           delay(SystemInstructionDelay);
  437.           ClrScr;
  438.           update_air_traffic(count, NumberOfLandedPlanes, count2);
  439.           update_platform_time_left(NumberOfLandedPlanes, target, count);
  440.           update_platformfile;
  441.           update_airtrafficfile(count2);
  442. {
  443.           for q:=1 to 30 do
  444.           begin
  445.             with platform[q] do
  446.             begin
  447.               writeln(airplane_no);
  448.               writeln(airplane_predicted_time_left);
  449.             end;
  450.             readln;
  451.           end;
  452. }
  453.         End;
  454.       End;
  455.       #27: exit;
  456.     End;  { case ch }
  457.   End;
  458. End.
  459.  

Still the range-check errors as i am not sure on what information some of the used values are based on.

Note that function update_air_traffic is my own, as well as added as much high() low() as possible (i might have gotten one or two wrong there as well).
« Last Edit: October 10, 2016, 07:27:04 pm by molly »

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: I am the new of pascal .please give me some HELP!
« Reply #33 on: October 10, 2016, 07:42:10 pm »
I semi-automated the program to never ask passwords, always accept landing planes, never accept taking off.

Then you get the runtime error with count2=21.

The file reading is accident prone.
Checking for eof() and the doing 2 readln's is plain wrong!
Also I screwed up the airtraffic.txt file, so that the order of lines was wrong. That did not go well.

Also I don't like a procedure that alters both a global variable and a var parameter (which happens to be global as well). Yuck.

For debugging purposes the program should be developed without the use of crt unit.
I cannot read anything back on my console when things go wrong.

Some thoughts:
Use Ini-files for the 2 textfiles, or use a binary file (file of record).
Alternatively use TStringList to read/write the textfiles.
Give variables a logical name.
Use the least possible number of global variables.
If a procedure alters a variable, then put it in the parameterlist.
Use empty lines between procedures.
As you did: define constants for the array type definitions (array[1..MaxNoPlanes] of ...)
Have all checks on (rangecheck, iocheck etc)
(I develop using Lazarus and all new projects have a debug and release builmode)
When using old-style reading/writing with files check IOResult after each read/write/reset/rewrite/close.
Re-use code (asking for password comes to mind).

Bart
« Last Edit: October 10, 2016, 07:44:03 pm by Bart »

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: I am the new of pascal .please give me some HELP!
« Reply #34 on: October 10, 2016, 09:22:04 pm »
Ah, i think i found the last bugger :D

Code: Pascal  [Select][+][-]
  1. procedure update_platform_time_left(Var aNrLandedPlanes,target,count:integer);
  2. begin
  3.   target := 0;
  4.   if count <= High(platform) then
  5.   begin
  6.     count := count+1;
  7.     with platform[count] do
  8.     begin
  9.       airplane_predicted_time_left := airplane_predicted_time_left - 1;
  10.       if (airplane_predicted_time_left<=0) and (airplane_no <> '') then
  11.       begin
  12.         target := count;
  13.         if (platform[target].airplane_no <> '$$$') then take_off(aNrLandedPlanes, target);
  14.         if (count <= High(platform))
  15.         then update_platform_time_left(aNrLandedPlanes, target, count);
  16.       end
  17.       else if count < High(platform)
  18.            then update_platform_time_left(aNrLandedPlanes, target, count);
  19.     end;
  20.   end;
  21. end;
  22.  

the highlighted line should (obviously) read: if count < High(platform) then.

Things seem to work with my version so far.

Still the strange/wierd comparison with $$$ that isn't set in any of the .airplane_no in the code. TS would need to confirm how that is to be dealt with (just as the comparisons against .airplane_no being 'empty').

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: I am the new of pascal .please give me some HELP!
« Reply #35 on: October 11, 2016, 06:05:26 pm »
@7vinbaby:
The logic part that is giving you issues is (afaik) the following:

You have two static arrays (one for the planes at the airport and one for the planes that are in the air).

For the platform array you got things pretty much covered, in that you always write (and restore) the complete array to and from file.

But, the airtraffic array is left behind somewhere along the way. The array is static while you add items dynamically to the array (you use the count2 variable to keep track of how many items are 'valid' in that array).

In principle that is not a problem but you have a logic error in there in the fact that whenever you 'transfer' a plane from "flying in the air" to "being grounded at an airport" that you do not update the static airtraffic array accordingly in order to reflect the new situation for the plane that was just 'removed' from that array.

Instead you simply decrease the number of planes in the air, and do not update the contents of the array.

imho you have mixed two things there. either you
a) use the airtraffic in a similar way as your platform array in that it has a fixed number of positions and every position reflect the current status. That way you can check for that status each time you require information from that array
or
b) simulate the array being dynamic (as you are doing right now) by keeping track of the number of "valid" items in there. But when you do so, also update the items in the array according to the action being taken (e.g. adding a plane to that array 'extends' things while removing an item from that array means you need to update the items accordingly, e.g. 'delete' the removed item form the array.

In my working version i have not added a solution for this yet, which is why i am able to see where things go wrong.

My advise would be to also make the airtraffic array 'static' in that all entries in that array _must_ contain valid information that can be accessed and make sense _all_ the time. That way you can simply designate an itemslot to be "empty", or containing a valid flight number. A real empty string would then become a non valid value for the field airplane_no.

But, i can not decide this for you. You would have to make sure that is what you actually want. I can imagine that you want the airtraffic.txt file as small as possible but as said, you then would have to make sure that the airtraffic array does not contain any 'invalid' entries.

A better advise would probably be to tell to use OOP (or at least advanced records so that you can add/use record functions), as doing so would make things much more clear and all the logic can then be kept inside the object/record itself. Make a good implemented object/record/class that follows your given set of rules and you would never have to take a look at it again.


Edit: version based on array 'moving' items
Code: Pascal  [Select][+][-]
  1. program air_traffic_control;
  2.  
  3. {$RANGECHECKS ON}{$OVERFLOWCHECKS ON}{$HINTS ON}
  4.  
  5. {.$DEFINE SKIP_PASSWORDPROMPT}
  6. {.$DEFINE SKIP_CHOICEPOSITIVE}
  7. {.$DEFINE SKIP_WAITS}
  8.  
  9. uses
  10.   Dos, Crt;
  11.  
  12. const
  13.   DefaultPW              = '';
  14.   SystemInstructionDelay = 1000;
  15.   TakeOffDelay           = 20000;
  16.   airtrafficfilename     = 'airtraffic.txt';
  17.   platformfilename       = 'airport_condition.txt';
  18.  
  19.  
  20. type
  21.   Tairport_platform =
  22.   record
  23.     airplane_no                  : string[30];
  24.     airplane_predicted_time_left : integer;
  25.   end;
  26.  
  27.   Tairtraffic_condition =
  28.   record
  29.     airplane_no                  : string[30];
  30.     airplane_landing_time_left   : integer;
  31.   end;
  32.  
  33.  
  34. var
  35.   hour                 : word = 0;
  36.   min                  : word = 0;
  37.   sec                  : word = 0;
  38.   msec                 : word = 0;
  39.   NrLandedPlanes       : integer = 0;   // previously named: Num
  40.   NrAirbornePlanes     : integer = 0;   // previously named: Count2
  41.   target               : integer = 0;
  42.   count                : integer;
  43.   z                    : integer;
  44.   platformfile,
  45.   airtrafficfile       : text;
  46.   platform             : array[1..30] of Tairport_platform;
  47.   airtraffic           : array[1..20] of Tairtraffic_condition;
  48.   ch                   : char;
  49.  
  50.  
  51. // Displays PromptMsg and awaits input from keyboard to match global PassWord
  52. // definition. If the PassWord does not match the HintMsg is displayed until
  53. // PassWord matches. In case HintMsg is empty then the screen is cleared and
  54. // the PromptMsg is repeated.
  55. // The routine loops until userinput matches password
  56. procedure PromptForPassWord(aPromptMsg: string = 'Password:'; aHintMsg: string = '');
  57. var
  58.   password  : string[20];
  59. begin
  60.   {$IFNDEF SKIP_PASSWORDPROMPT}
  61.   repeat
  62.     write(aPromptMsg);
  63.     readln(password);
  64.  
  65.     if (aHintMsg <> '') then
  66.     begin
  67.       if (password <> DefaultPW) then WriteLn(aHintMsg);
  68.     end
  69.     else ClrScr;
  70.   until password=DefaultPW;
  71.   {$ENDIF}
  72. end;
  73.  
  74.  
  75. // Copy from http://www.freepascal.org/docs-html/rtl/system/reset.html
  76. // Note that the original code had an error in that if the file does not
  77. // exist the example is still atempting to close the file -> error.
  78. // This code has that issue fixed.
  79. // Check if a given filename/path exists and returns a true/false answer
  80. function FileExists (aFileName: string) : boolean;
  81. var
  82.   f : File;
  83. begin
  84.   if (aFileName <> '') then
  85.   begin
  86.     {$i-}
  87.     Assign (f, aFileName);
  88.     Reset (f);
  89.     {$i+}
  90.     if (IOResult = 0) then
  91.     begin
  92.       Close (f);
  93.       Exit(true);
  94.     end;
  95.   end;
  96.   FileExists := false;
  97. end;
  98.  
  99.  
  100. // Creates a new texfile from given Filename and returns filepointer
  101. // in FileVar. In case things go wrong the function halts the program (panic).
  102. procedure CreateNewTextFile(aFileName: string; var aFileVar: Text);
  103. var
  104.   LastError : Word = 0;
  105. begin
  106.   if (aFileName <> '') then
  107.   begin
  108.     {$i-}
  109.     Assign (aFileVar, aFileName);
  110.     Rewrite (aFileVar);
  111.     {$i+}
  112.     LastError := IoResult;
  113.  
  114.     if (LastError = 0) then Close(aFileVar) else
  115.     begin
  116.       WriteLn('Fatal error ! Unable to create file ', aFileName, ' (IOResult = ', LastError, ')');
  117.       Halt(1);
  118.     end;
  119.   end
  120.   else
  121.   begin
  122.     WriteLn('Fatal error ! Empty Filename');
  123.     Halt(1);
  124.   end;
  125. end;
  126.  
  127.  
  128. procedure user_display;
  129. type
  130.   TDayType = (Sun,Mon,Tue,Wed,Thu,Fri,Sat);
  131. var
  132.   YY        : Word = 0;
  133.   MM        : word = 0;
  134.   DD        : word = 0;
  135.   DayOfWeek : Word = 0;
  136.   hour      : Word = 0;
  137.   min       : Word = 0;
  138.   sec       : Word = 0;
  139.   msec      : Word = 0;
  140.   today     : TDayType;
  141. begin
  142.   textbackground(black);
  143.   ClrScr;
  144.   Getdate(YY,MM,DD,DayOfWeek);
  145.   GetTime(hour,min,sec,msec);
  146.   Today := TDayType(DayOfWeek);
  147.   textcolor(yellow);
  148.   WriteLn('Welcome to execute air traffic control');
  149.  
  150.   textcolor(yellow);
  151.   PromptForPassword('PassWord:', 'Wrong password, enter again');
  152.  
  153.   ClrScr;
  154.   WriteLn('Day of Today:',DD,'/',MM,'/',YY,',',Today);
  155.   WriteLn('Current time: ',hour,':',min,':',sec);
  156.   WriteLn('Now start the system of air traffic control management');
  157.  
  158.   textcolor(yellow);
  159.   PromptForPassword('PassWord:', 'Wrong password, enter again');
  160.  
  161.   ClrScr;
  162. end;
  163.  
  164.  
  165. procedure input_airtraffic(var aNrAirbornePlanes:integer);
  166. var n: integer;
  167. begin
  168.   for n:= Low(airtraffic) to High(airtraffic)
  169.     do airtraffic[n].airplane_no := '';
  170.  
  171.   aNrAirbornePlanes := 0;
  172.  
  173.   if not FileExists(airtrafficfilename) then
  174.   begin
  175.     CreateNewTextFile(airtrafficfilename, airtrafficfile);
  176.  
  177.     // AirTraffic must at least consist of one (valid) entry
  178.     // otherwise the rest of the code won't run properly as condition
  179.     // "zero planes in sky" plus "zero planes on ground" is treated as
  180.     // nothing to do (it might happen on startup so account for it here).
  181.     // ToDo: Add IOResult checking
  182.     Append(airtrafficfile);
  183.     WriteLn(airtrafficfile, 'fes2135487');
  184.     WriteLn(airtrafficfile, '3');
  185.     WriteLn(airtrafficfile, 'qwe7634153');
  186.     WriteLn(airtrafficfile, '7');
  187.     WriteLn(airtrafficfile, 'jfd1325748');
  188.     WriteLn(airtrafficfile, '11');
  189.     Close(airtrafficfile);
  190.   end;
  191.  
  192.   // ToDo: Add IOResult checking
  193.   Assign(airtrafficfile, airtrafficfilename);
  194.   Reset(airtrafficfile);
  195.  
  196.   // ToDo: Add IOResult checking
  197.   while not eof(airtrafficfile) do
  198.   begin
  199.     aNrAirbornePlanes := aNrAirbornePlanes + 1;
  200.     with airtraffic[aNrAirbornePlanes] do
  201.     begin
  202.       readln(airtrafficfile,airplane_no);
  203.       readln(airtrafficfile,airplane_landing_time_left);
  204.     end;
  205.   end;
  206.  
  207.   close(airtrafficfile);
  208. end;
  209.  
  210.  
  211. procedure input_platform_condition(var aNrLandedPlanes: integer);
  212. var
  213.   idx, n : integer;
  214. begin
  215.   Writeln('dumping airport plane stats');
  216.   aNrLandedPlanes :=0;
  217.   for n := Low(platform) to High(platform)
  218.     do platform[n].airplane_no := '';
  219.  
  220.   if not FileExists(platformfilename) then
  221.   begin
  222.     CreateNewTextFile(platformfilename, platformfile);
  223.   end;
  224.  
  225.   // ToDo: Add IOResult checking
  226.   Assign(platformfile, platformfilename);
  227.   Reset(platformfile);
  228.  
  229.   // ToDo: Add IOResult checking
  230.   idx := 0;
  231.   while not eof(platformfile) do
  232.   begin
  233.     if (idx < High(platform)) then inc(idx) else break;
  234.  
  235.     with platform[idx] do
  236.     begin
  237.       readln(platformfile,airplane_no);
  238.       readln(platformfile,airplane_predicted_time_left);
  239.  
  240.       if (airplane_no <> '') then
  241.       begin
  242.         aNrLandedPlanes := aNrLandedPlanes + 1;
  243.         Writeln('[ok] Plane = "', airplane_no, '" predicted_time_left = ', airplane_predicted_time_left);
  244.       end
  245.       else
  246.         Writeln('[xx] Plane = "', airplane_no, '" predicted_time_left = ', airplane_predicted_time_left);
  247.     end;
  248.   end;
  249.   close(platformfile);
  250.  
  251.   WriteLn('Press enter to continue'); ReadLn;
  252. end;
  253.  
  254.  
  255. procedure take_off(var aNrLandedPlanes,target:integer);
  256. var
  257.   choice: char;
  258. begin
  259.   with platform[target] do
  260.   begin
  261.     repeat
  262.       write('plane ',airplane_no,'is ready to take off,asking for permission(Y/N)?');
  263.       choice := ReadKey;
  264.       if not( Upcase(choice) in ['Y','N'] )
  265.       then write('Wrong input choice,please input choice again(Y/N):');
  266.       ClrScr;
  267.     until (Upcase(choice) In ['Y','N']);
  268.  
  269.     if  (UpCase(choice)='N')
  270.     then airplane_predicted_time_left := 5 else
  271.     begin
  272.       PromptForPassWord('Enter password to execute this order:');
  273.  
  274.       WriteLn('please wait for the processing of taking off.......');
  275.       Delay(TakeOffDelay);
  276.       writeln('plane ',airplane_no,'has been taken off');
  277.       ReadLn;
  278.       aNrLandedPlanes := aNrLandedPlanes - 1;
  279.       airplane_no := '$$$';
  280.       airplane_predicted_time_left := 999;
  281.     end;
  282.   end;
  283. end;
  284.  
  285.  
  286. procedure update_platform_time_left(var aNrLandedPlanes, target, count: integer);
  287. begin
  288.   target := 0;
  289. //@  if count <= High(platform) then
  290.   if count < High(platform) then
  291.   begin
  292.     count := count+1;
  293.     with platform[count] do
  294.     begin
  295.       airplane_predicted_time_left := airplane_predicted_time_left - 1;
  296.       if (airplane_predicted_time_left<=0) and (airplane_no <> '') then
  297.       begin
  298.         target := count;
  299.         if (platform[target].airplane_no <> '$$$') then take_off(aNrLandedPlanes, target);
  300.         if (count <= High(platform))
  301.         then update_platform_time_left(aNrLandedPlanes, target, count);
  302.       end
  303.       else if count < High(platform)
  304.            then update_platform_time_left(aNrLandedPlanes, target, count);
  305.     end;
  306.   end;
  307. end;
  308.  
  309.  
  310. procedure update_air_traffic(count:integer; var aNrLandedPlanes, aNrAirbornePlanes: integer);
  311. var
  312.   choice1: char;
  313.   target,count1, n: integer;
  314. begin
  315.   n := 1;
  316.   target := 0;
  317.   count1 := 0;
  318.   count := count+1;
  319.  
  320.   if count<=aNrAirbornePlanes then
  321.   begin
  322.     with airtraffic[count] do
  323.     begin
  324.       airplane_landing_time_left := airplane_landing_time_left-1;
  325.       if (airplane_landing_time_left<=0) and (airplane_no<>'') then
  326.       begin
  327.         repeat
  328.           write('airplane ',airplane_no,' is asking for the permission of landing(Y/N):');
  329.           {$IFDEF SKIP_CHOICEPOSITIVE}
  330.           choice1 := 'y';
  331.           {$ELSE}
  332.           choice1 := ReadKey;
  333.           {$ENDIF}
  334.         until UpCase(choice1) in ['Y', 'N'];
  335.         WriteLn;
  336.  
  337.         PromptForPassWord('Please input password to continue:');
  338.  
  339.         case Upcase(choice1) of
  340.           'Y':
  341.           begin
  342.             Writeln('chosen to allow landing, searching for a free platform');
  343.  
  344.             target := -1; // assume failure
  345.             for count1 := Low(platform) to High(platform) do
  346.             begin
  347.               if platform[count1].airplane_no = '' then
  348.               begin
  349.                 target := count1;
  350.                 break;
  351.               end;
  352.             end;
  353.  
  354.             // WriteLn('The target platform is ', target);
  355.             // WriteLn('The value of count1 is ', count1);
  356.  
  357.             if (target < 1) then
  358.             Begin
  359.               writeln('No platform remain, please stay on the air');
  360.               airplane_landing_time_left := 5;
  361.             end
  362.             else
  363.             begin
  364.               {$IFNDEF SKIP_WAITS}
  365.               write('airplane ',airplane_no, ' landing to platform ',target);
  366.               readln;
  367.               {$ENDIF}
  368.               platform[target].airplane_no := airplane_no;
  369.               platform[target].airplane_predicted_time_left := 400;
  370.               airplane_no := '';
  371.               aNrLandedPlanes := aNrLandedPlanes + 1;
  372.  
  373.               // Update airtraffic array, e.g. 'remove' item
  374.               for n := Succ(count) to High(AirTraffic) do
  375.               begin
  376.                 // copy/transfer
  377.                 airtraffic[Pred(n)].airplane_no                := airtraffic[n].airplane_no;
  378.                 airtraffic[Pred(n)].airplane_landing_time_left := airtraffic[n].airplane_landing_time_left;
  379.               end;
  380.               // Always 'clear' last item in list as things moved. This also
  381.               // takes care of things in case the above loop did not execute.
  382.               airtraffic[High(AirTraffic)].airplane_no := '';
  383.               airtraffic[High(AirTraffic)].airplane_landing_time_left := 0;
  384.  
  385.               // We now have one less plane in the air.
  386.               aNrAirbornePlanes := aNrAirbornePlanes - 1;
  387.             end;
  388. //@         aNrAirbornePlanes := aNrAirbornePlanes - 1;
  389.           end;
  390.           'N': airplane_landing_time_left := 5
  391.         end  { case choice }
  392.       end
  393.  
  394.       else
  395.  
  396. //@   if count <= High(airtraffic) then
  397.       if count < High(airtraffic) then
  398.       begin
  399.         update_air_traffic(count, aNrLandedPlanes, aNrAirbornePlanes);
  400.       end;
  401.     end;
  402.   end;
  403. end;
  404.  
  405.  
  406. procedure generate_airplane_no(var aNrAirbornePlanes: integer);
  407. Var
  408.   x: array[1..3] of char;
  409.   y: array[1..7] of char;
  410.   z: string[30] = '';
  411.   count, abc: integer;
  412. begin
  413.   if (aNrAirbornePlanes < High(airtraffic)) then
  414.   begin
  415.     aNrAirbornePlanes := aNrAirbornePlanes + 1;
  416.     for count:= Low(x) to High(x)
  417.       do x[count] := ' ';
  418.     for count:= Low(y) to High(y)
  419.       do y[count] := ' ';
  420.  
  421.     if aNrAirbornePlanes <= High(airtraffic) then
  422.     begin
  423.       randomize;
  424.       abc := random(9);
  425.       for count:= Low(x) to High(x)
  426.         do x[count] := chr(random(26)+65);
  427.       for count:= Low(y) to High(y)
  428.         do y[count] := chr(random(10)+48);
  429.       for count := 1 To 2
  430.         do z := concat(z, x[count]);
  431.       for count := low(y) to High(y)
  432.         do z := concat(z, y[count]);
  433.  
  434.       with airtraffic[aNrAirbornePlanes] do
  435.       begin
  436.         airplane_no := z;
  437.         airplane_landing_time_left := random(20)+ 1;  // ??? High(airtraffic) intended ?
  438.         {$IFNDEF SKIP_WAITS}
  439.         readln;
  440.         {$ENDIF}
  441.       end;
  442.     end;
  443.   end;
  444. end;
  445.  
  446.  
  447. procedure update_platformfile;
  448. var
  449.   n: integer;
  450. begin
  451.   rewrite(platformfile);
  452.   for n := Low(PlatForm) to High(Platform) do
  453.   begin
  454.     with platform[n] do
  455.     begin
  456.       writeln(platformfile,airplane_no);
  457.       writeln(platformfile,airplane_predicted_time_left);
  458.     end;
  459.   end;
  460.   close(platformfile);
  461. end;
  462.  
  463.  
  464. procedure update_airtrafficfile(var aNrAirbornePlanes: integer);
  465. var n: integer;
  466. begin
  467.   rewrite(airtrafficfile);
  468.   for n := Low(AirTraffic) to aNrAirbornePlanes do
  469.   begin
  470.     with airtraffic[n] do
  471.     begin
  472.       writeln(airtrafficfile, airplane_no);
  473.       writeln(airtrafficfile, airplane_landing_time_left);
  474.     end;
  475.   end;
  476.   close(airtrafficfile);
  477. end;
  478.  
  479.  
  480. begin
  481.   NrAirbornePlanes := 0;
  482.   user_display;
  483.   input_airtraffic(NrAirbornePlanes);
  484.   input_platform_condition(NrLandedPlanes);
  485.  
  486.   while (NrLandedPlanes >= 0) do
  487.   begin
  488.     ClrScr;
  489.     GetTime(hour,min,sec,msec);
  490.     writeln('Current time: ',hour,':',min,':',sec);
  491.     z := 0;
  492.     writeln('There are total ', NrLandedPlanes, ' planes in the airport now');
  493.     writeln('There are total ', NrAirbornePlanes, ' planes are waiting  for landing');
  494.     count := 0;
  495.     repeat
  496.       writeln('Press Enter to continue/Press ESC to exit');
  497.       ch := ReadKey;
  498.       ClrScr;
  499.     until (ch=#27) or (ch=#13);
  500.  
  501.     case ch of
  502.       #13:
  503.       begin
  504.         if ( (NrLandedPlanes=0) and (NrAirbornePlanes=0) ) then
  505.         begin
  506.           WriteLn('No plane information found, please wait until plane land/take off....');
  507.           WriteLn('press ENTER to continue!!');
  508.           repeat
  509.             ch := ReadKey;
  510.           until (ch=#13);
  511.           ClrScr;
  512.         end
  513.         else
  514.         begin
  515.           generate_airplane_no(NrAirbornePlanes);
  516.           ClrScr;
  517.           WriteLn('Waiting for the system instruction.....');
  518.           Delay(SystemInstructionDelay);
  519.           ClrScr;
  520.           update_air_traffic(count, NrLandedPlanes, NrAirbornePlanes);
  521.           update_platform_time_left(NrLandedPlanes, target, count);
  522.           update_platformfile;
  523.           update_airtrafficfile(NrAirbornePlanes);
  524.         end;
  525.       end;
  526.       #27: exit;
  527.     end;  { case ch }
  528.   end;
  529. end.
  530.  
« Last Edit: October 11, 2016, 08:04:39 pm by molly »

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: I am the new of pascal .please give me some HELP!
« Reply #36 on: October 12, 2016, 02:50:31 pm »
I could not resist.
  • I refactored some more.
  • Wrote a general purpose PromptForCharacter function.
  • Added IO checking with verbose output
  • Tried to get rid of planes with invalid numbers
  • More defines to automate the program
  • Visual feedback on delays
  • Added {$mode objfpc}, needed for default parameters and var-initialization
  • Defined InvalidAirplaneNo and InvalidTimeLeft
  • Defined type StringAirplainNo
  • Tried to sanitize string literals (start each sentence with a capital)

I could not put the source inside code-tags any more, the board gave me this error:
The message exceeds the maximum allowed length (20000 characters).

Attached air.zip contains sourcecode (air.lpr) and for use with Lazarus as editor also the .lpi.

Bart

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: I am the new of pascal .please give me some HELP!
« Reply #37 on: October 12, 2016, 06:11:58 pm »
Nice one Bart ! Thank you for the additions.

My idea about CharPrompt was to make it a true/false returning function and giving it true/false set of chars together with the prompt. Yours is doing very fine as well :)

I can only have admiration for the simplicity of the IOChecking implementation. Gosh, what we had to do for all those years to account for each and every possible failure. I haven't used simple textfiles like that for ages so, i was not sure how to approach. It makes me appreciate your implementation/solution the more.

I have one (unrelated to your code) question though: I noticed that code-tools in my lazarus seems to be tripping over the variable name platform. Did i miss it is/was a keyword or modifier somewhere ?
« Last Edit: October 12, 2016, 06:25:08 pm by molly »

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: I am the new of pascal .please give me some HELP!
« Reply #38 on: October 12, 2016, 10:55:56 pm »
platform may very well be a modifier.

About IOChecking: notice that the whole block /procedure will halt the application on 1 single IOError.
Thank god for try..except/try..finally blocks.
In the old days it really was hard.

This piece of code can be rewritten in modern equivalents and it would be so much simpler.

Bart

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: I am the new of pascal .please give me some HELP!
« Reply #39 on: October 12, 2016, 11:03:54 pm »
platform is indeed a modifier (a hint directive).
You can use it with impunity by escaping it with & though (&platform).

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: I am the new of pascal .please give me some HELP!
« Reply #40 on: October 12, 2016, 11:27:36 pm »
@Bart:
Yes i noticed it is in blocks. Well... there (imho) actually isn't a good solution to begin with because of the way things are implemented. I feel so restricted working with only fpc procedural basics. The code would greatly benefit when going oop or at least use some modern language features. Using advanced records alone would already help tremendously. iow, i agree fully with your opinion.


Ah. thank you for the confirmation howardpc (and also Bart). That explain things :)

At least i was able to find the documentation on that directive now. The ampersand indeed neatly gets rid of nasty side-effects.

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: I am the new of pascal .please give me some HELP!
« Reply #41 on: October 13, 2016, 06:39:37 pm »
Since I have nothing better to do with my life  :D

A rewritten version of the code.
It uses TCustomApplication so it is easy to catch all exceptions in one place, and modern classes to load and save files.
Arrays are dynamical now.
Used one type for the record definition of an airplane.
File access is only on startup and close.
Procedures do what they say, they do not have trange by-effects.

Pseudo-code in the main file says what it is supposed to do.

Of course much room for improvement.

Bart

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: I am the new of pascal .please give me some HELP!
« Reply #42 on: October 13, 2016, 10:45:46 pm »
Small update: it does not require *.txt files at startup.

Bart

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: I am the new of pascal .please give me some HELP!
« Reply #43 on: October 15, 2016, 05:05:57 pm »
Because I'm pathetic  :-[

Some simplifications.
All defines now work, so it can be run in fully automatic mode (and you can still quit by pressing escape (and have some patience then)).

Now it's time to so something usefull  O:-)

Bart

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: I am the new of pascal .please give me some HELP!
« Reply #44 on: October 16, 2016, 11:14:37 pm »
Planes now carry fuell and will crash if they run out of it...

Bart

 

TinyPortal © 2005-2018