-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlunar.cob
380 lines (316 loc) · 10.4 KB
/
lunar.cob
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
*> Translation of
*> <http://www.cs.brandeis.edu/~storer/LunarLander/LunarLander/LunarLanderListing.jpg>
*> by Jim Storer from FOCAL to COBOL.
IDENTIFICATION DIVISION.
PROGRAM-ID. LunarLander.
DATA DIVISION.
WORKING-STORAGE SECTION.
*> Constants
01 FeetPerMile PIC 9(4) VALUE 5280 USAGE COMP.
01 SecPerHour PIC 9(4) VALUE 3600 USAGE COMP.
01 BlankLine PIC X VALUE SPACE.
*> Global variables from original FOCAL code:
*>
*> A - Altitude (miles)
*> G - Gravity
*> I - Intermediate altitude (miles)
*> J - Intermediate velocity (miles/sec)
*> K - Fuel rate (lbs/sec)
*> L - Elapsed time (sec)
*> M - Total weight (lbs)
*> N - Empty weight (lbs, Note: M - N is remaining fuel weight)
*> Q - Temporary working variable
*> S - Time elapsed in current 10-second turn (sec)
*> T - Time remaining in current 10-second turn (sec)
*> V - Downward speed (miles/sec)
*> W - Temporary working variable
*> Z - Thrust per pound of fuel burned
01 Altitude PIC S9(6)V9(10) USAGE COMP.
01 Gravity PIC S9(6)V9(10) USAGE COMP.
01 I PIC S9(6)V9(10) USAGE COMP.
01 J PIC S9(6)V9(10) USAGE COMP.
01 FuelRate PIC S9(6)V9(10) USAGE COMP.
01 ElapsedTime PIC S9(6)V9(10) USAGE COMP.
01 Weight PIC S9(6)V9(10) USAGE COMP.
01 EmptyWeight PIC S9(6)V9(10) USAGE COMP.
01 Q PIC S9(6)V9(10) USAGE COMP.
01 S PIC S9(6)V9(10) USAGE COMP.
01 T PIC S9(6)V9(10) USAGE COMP.
01 Velocity PIC S9(6)V9(10) USAGE COMP.
01 W PIC S9(6)V9(10) USAGE COMP.
01 Z PIC S9(6)V9(10) USAGE COMP.
*> Variables used by Simulate and related paragraphs.
01 GameOverFlag PIC 9.
88 GameIsNotOver VALUE 0.
88 GameIsOver VALUE 1.
01 Q2 PIC S9(6)V9(10) USAGE COMP.
01 Q3 PIC S9(6)V9(10) USAGE COMP.
01 Q4 PIC S9(6)V9(10) USAGE COMP.
01 Q5 PIC S9(6)V9(10) USAGE COMP.
*> Output Formatting
01 StatusRowHeadings.
02 FILLER PIC X(12) VALUE "TIME,SECS".
02 FILLER PIC X(22) VALUE "ALTITUDE,MILES+FEET".
02 FILLER PIC X(15) VALUE "VELOCITY,MPH".
02 FILLER PIC X(11) VALUE "FUEL,LBS".
02 FILLER PIC X(9) VALUE "FUEL RATE".
01 StatusRowData.
02 ElapsedTimeDisplay PIC -(6)9.
02 AltitudeMilesDisplay PIC -(15)9.
02 AltitudeFeetDisplay PIC -(6)9.
02 VelocityMphDisplay PIC -(11)9.99.
02 FuelRemainingDisplay PIC -(9)9.9.
02 FILLER PIC X(6) VALUE SPACES.
01 NotPossibleMessage.
02 FILLER PIC X(12) VALUE "NOT POSSIBLE".
02 FILLER PIC X(51) VALUE ALL '.'.
01 FuelOutTimeDisplay PIC -(4)9.99.
01 ContactTimeDisplay PIC -(4)9.99.
01 ImpactVelocityDisplay PIC -(4)9.99.
01 FuelLeftDisplay PIC -(4)9.99.
01 LunarCraterDisplay PIC -(4)9.99.
*> User Input
01 FuelRateAnswer PIC 999.
88 IsValidFuelRate VALUE 0, 8 THRU 200.
01 TryAgainAnswer PIC X.
88 TryAgain VALUE "Y", "y".
88 DontTryAgain VALUE "N", "n".
PROCEDURE DIVISION.
*> (01.04 in original FOCAL code)
Begin.
DISPLAY "CONTROL CALLING LUNAR MODULE. MANUAL CONTROL IS NECESSARY"
DISPLAY "YOU MAY RESET FUEL RATE K EACH 10 SECS TO 0 OR ANY VALUE"
DISPLAY "BETWEEN 8 & 200 LBS/SEC. YOU'VE 16000 LBS FUEL. ESTIMATED"
DISPLAY "FREE FALL IMPACT TIME-120 SECS. CAPSULE WEIGHT-32500 LBS"
DISPLAY BlankLine
DISPLAY BlankLine
PERFORM WITH TEST AFTER UNTIL DontTryAgain
PERFORM PlayGame
DISPLAY BlankLine
DISPLAY BlankLine
DISPLAY BlankLine
DISPLAY "TRY AGAIN?"
PERFORM WITH TEST AFTER UNTIL TryAgain OR DontTryAgain
DISPLAY "(ANS. YES OR NO):" NO ADVANCING
ACCEPT TryAgainAnswer
*>TEST:DISPLAY TryAgainAnswer
END-PERFORM
END-PERFORM
DISPLAY "CONTROL OUT"
DISPLAY BlankLine
DISPLAY BlankLine
STOP RUN.
*> Play game until landing or crash.
PlayGame.
DISPLAY "FIRST RADAR CHECK COMING UP"
DISPLAY BlankLine
DISPLAY BlankLine
DISPLAY "COMMENCE LANDING PROCEDURE"
DISPLAY StatusRowHeadings
MOVE 120 TO Altitude
MOVE 1 TO Velocity
MOVE 32500 TO Weight
MOVE 16500 TO EmptyWeight
MOVE 0.001 TO Gravity
MOVE 1.8 TO Z
INITIALIZE ElapsedTime
SET GameIsNotOver TO TRUE
PERFORM UNTIL GameIsOver
PERFORM GetFuelRate
MOVE 10 TO T
PERFORM Simulate
END-PERFORM
EXIT.
*> Display current status and prompt for new Fuel-Rate value until
*> valid answer is given.
GetFuelRate.
COMPUTE
ElapsedTimeDisplay ROUNDED = ElapsedTime
END-COMPUTE
MOVE FUNCTION INTEGER-PART(Altitude) TO AltitudeMilesDisplay
COMPUTE
AltitudeFeetDisplay ROUNDED =
(Altitude - FUNCTION INTEGER-PART(Altitude)) * FeetPerMile
END-COMPUTE
MULTIPLY
Velocity BY SecPerHour
GIVING VelocityMphDisplay ROUNDED
END-MULTIPLY
SUBTRACT
EmptyWeight FROM Weight
GIVING FuelRemainingDisplay ROUNDED
END-SUBTRACT
DISPLAY StatusRowData NO ADVANCING
PERFORM WITH TEST AFTER UNTIL IsValidFuelRate
DISPLAY "K=:" NO ADVANCING
ACCEPT FuelRateAnswer
*>TEST:DISPLAY FuelRateAnswer
IF IsValidFuelRate THEN
MOVE FuelRateAnswer TO FuelRate
ELSE
DISPLAY NotPossibleMessage NO ADVANCING
END-IF
END-PERFORM
EXIT.
*> Simulate T seconds using current fuel rate.
*> If out of fuel, continue until contact with surface.
*> On contact with surface, determine outcome and display score.
*> (03.10 in original FOCAL code)
Simulate.
PERFORM UNTIL GameIsOver OR T < 0.001
IF (Weight - EmptyWeight) < 0.001 THEN
PERFORM FuelOut
ELSE
MOVE T TO S
IF (S * FuelRate) > (Weight - EmptyWeight) THEN
COMPUTE
S ROUNDED = (Weight - EmptyWeight) / FuelRate
END-COMPUTE
END-IF
PERFORM ApplyThrust
IF I <= 0 THEN
PERFORM UpdateUntilContact
ELSE
IF Velocity > 0 AND J < 0 THEN
PERFORM ApplyThrustLoop
ELSE
PERFORM UpdateLanderState
END-IF
END-IF
END-IF
END-PERFORM
EXIT.
*> (04.10 in original FOCAL code)
FuelOut.
COMPUTE
FuelOutTimeDisplay ROUNDED = ElapsedTime
END-COMPUTE
DISPLAY "FUEL OUT AT " FuelOutTimeDisplay " SECS"
COMPUTE
S ROUNDED =
(FUNCTION SQRT(Velocity**2 + 2 * Altitude * Gravity)
- Velocity)
/ Gravity
END-COMPUTE
COMPUTE
Velocity ROUNDED = Velocity + Gravity * S
END-COMPUTE
ADD
S to ElapsedTime ROUNDED
END-ADD
PERFORM Contact
EXIT.
*> Handle touchdown/crash
*> (05.10 in original FOCAL code)
Contact.
COMPUTE
ContactTimeDisplay ROUNDED = ElapsedTime
END-COMPUTE
DISPLAY "ON THE MOON AT " ContactTimeDisplay " SECS"
*> W is velocity in miles-per-hour
MULTIPLY
SecPerHour BY Velocity
GIVING W ROUNDED
END-MULTIPLY
COMPUTE
ImpactVelocityDisplay ROUNDED = W
END-COMPUTE
DISPLAY "IMPACT VELOCITY OF " ImpactVelocityDisplay " M.P.H."
SUBTRACT
EmptyWeight FROM Weight
GIVING FuelLeftDisplay ROUNDED
END-SUBTRACT
DISPLAY "FUEL LEFT: " FuelLeftDisplay " LBS"
EVALUATE W
WHEN <= 1 DISPLAY "PERFECT LANDING !-(LUCKY)"
WHEN <= 10 DISPLAY "GOOD LANDING-(COULD BE BETTER)"
WHEN <= 22 DISPLAY "CONGRATULATIONS ON A POOR LANDING"
WHEN <= 40 DISPLAY "CRAFT DAMAGE. GOOD LUCK"
WHEN <= 60 DISPLAY "CRASH LANDING-YOU'VE 5 HRS OXYGEN"
WHEN OTHER
PERFORM
DISPLAY "SORRY,BUT THERE WERE NO SURVIVORS-YOU BLEW IT!"
COMPUTE
LunarCraterDisplay ROUNDED = W * 0.277777
END-COMPUTE
DISPLAY
"IN FACT YOU BLASTED A NEW LUNAR CRATER "
LunarCraterDisplay " FT. DEEP"
END-PERFORM
END-EVALUATE
SET GameIsOver TO TRUE
EXIT.
*> (06.10 in original FOCAL code)
UpdateLanderState.
ADD
S TO ElapsedTime
END-ADD
SUBTRACT
S FROM T
END-SUBTRACT
COMPUTE
Weight ROUNDED = Weight - (S * FuelRate)
END-COMPUTE
MOVE I TO Altitude
MOVE J TO Velocity
EXIT.
*> (07.10 in original FOCAL code)
UpdateUntilContact.
PERFORM UNTIL S < 0.005
COMPUTE
S ROUNDED =
(2 * Altitude)
/ (Velocity
+ FUNCTION SQRT(
Velocity**2 + 2 * Altitude
* (Gravity - Z * FuelRate / Weight)))
END-COMPUTE
PERFORM ApplyThrust
PERFORM UpdateLanderState
END-PERFORM
PERFORM Contact
EXIT.
*> (08.10 in original FOCAL code)
ApplyThrustLoop.
PERFORM WITH TEST AFTER UNTIL (I <= 0) OR (-J < 0) OR (Velocity <= 0)
COMPUTE
W ROUNDED = (1 - Weight * Gravity / (Z * FuelRate)) / 2
END-COMPUTE
COMPUTE
S ROUNDED =
Weight * Velocity
/ (Z * FuelRate
* (W + FUNCTION SQRT(W**2 + Velocity / Z)))
+ 0.05
END-COMPUTE
PERFORM ApplyThrust
IF I <= 0 THEN
PERFORM UpdateUntilContact
ELSE
PERFORM UpdateLanderState
END-IF
END-PERFORM
EXIT.
*> (09.10 in original FOCAL code)
ApplyThrust.
COMPUTE
Q ROUNDED = S * FuelRate / Weight
END-COMPUTE
COMPUTE Q2 ROUNDED = Q ** 2 END-COMPUTE
COMPUTE Q3 ROUNDED = Q ** 3 END-COMPUTE
COMPUTE Q4 ROUNDED = Q ** 4 END-COMPUTE
COMPUTE Q5 ROUNDED = Q ** 5 END-COMPUTE
COMPUTE
J ROUNDED =
Velocity
+ Gravity * S
+ Z * (-Q - Q2/2 - Q3/3 - Q4/4 - Q5/5)
END-COMPUTE
COMPUTE
I ROUNDED =
Altitude
- Gravity * S * S / 2
- Velocity * S
+ Z * S * (Q/2 + Q2/6 + Q3/12 + Q4/20 + Q5/30)
END-COMPUTE
EXIT.