### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

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

#### Bart

• Hero Member
• Posts: 3899
##### 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: 3899
##### Re: I am the new of pascal .please give me some HELP!
« Reply #31 on: October 10, 2016, 07:06:22 pm »
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: 2345
##### 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;
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);
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:');
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
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
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;
159. Begin
160.   With platform[target] Do
161.     Begin
162.       Repeat
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:');
176.             ClrScr;
178.           writeln('please wait for the processing of taking off.......');
179.           delay(20000);
180.           writeln('plane ',airplane_no,'has been taken off');
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;
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):');
235.         Until (choice1='y') Or (choice1='Y') Or (choice1='n') Or (choice1='N');
236.         Repeat
239.           ClrScr;
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);
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) ?
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');
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
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;
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: 3899
##### 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)

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

#### molly

• Hero Member
• Posts: 2345
##### 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

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: 2345
##### 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.
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
57. var
59. begin
61.   repeat
62.     write(aPromptMsg);
64.
65.     if (aHintMsg <> '') then
66.     begin
67.       if (password <> DefaultPW) then WriteLn(aHintMsg);
68.     end
69.     else ClrScr;
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);
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);
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
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
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
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
273.
274.       WriteLn('please wait for the processing of taking off.......');
275.       Delay(TakeOffDelay);
276.       writeln('plane ',airplane_no,'has been taken off');
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}
333.           {\$ENDIF}
334.         until UpCase(choice1) in ['Y', 'N'];
335.         WriteLn;
336.
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);
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}
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');
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
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: 3899
##### 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: 2345
##### 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: 3899
##### 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: 3517
##### 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: 2345
##### 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: 3899
##### 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

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: 3899
##### 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: 3899
##### 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

Bart

#### Bart

• Hero Member
• Posts: 3899
##### 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