Post Reply 
Rocket Game - from 101 BASIC Computer Games
08-16-2015, 04:39 PM (This post was last modified: 08-19-2015 01:36 AM by smp.)
Post: #1
Rocket Game - from 101 BASIC Computer Games
I am attempting to convert the old Rocket BASIC game (from 101 BASIC Computer Games by Digital Equipment Corporation) to run on my HP Prime calculator. I'm doing this as one of my exercises in learning to program on the HP Prime, and also to end up with one of the vintage games I love running on my calculator.

Here's the original BASIC code:
Code:

2 PRINT "THIS IS A COMPUTER SIMULATION OF AN APOLLO LUNAR"
3 PRINT "LANDING CAPSULE, "\PRINT\PRINT
4 PRINT "THE ON-BOARD COMPUTER HAS FAILED (IT WASN'T MADE BY"
5 PRINT "DIGITAL) SO YOU HAVE TO LAND THE CAPSULE MANUALLY"
6 PRINT\PRINT "SET BURN RATE OF RETRO ROCKETS TO ANY VALUE BETWEEN"
7 PRINT "0 (FREE FALL) AND 200 (MAXIMUM BURN) POUNDS PER SECOND"
8 PRINT "SET NEW BURN RATE EVERY 10 SECONDS. "\PRINT
9 PRINT "CAPSULE WEIGHT 32,500 LBS, FUEL WEIGHTT 16,500 LBS"
19 PRINT\PRINT\PRINT "GOOD LUCK!!!"
11 L=0
13 PRINT\PRINT "SEC", "MI + FT", "MPH", "LB FUEL", "BURN RATE"\PRINT
15 A=120\V=1\M=33000\N=16500\G=1E-3\Z=1.8
21 PRINT L,INT(A); INT(5280*(A-INT(A))),3600*V,M-N,\INPUT K\T=10
31 IF M-N<.001 THEN 41\IF T<.001 THEN 21\S=T\IF M>N+S*K THEN 35
32 S=(M-N)/K
35 GOSUB 91\IF I<=0 THEN 71\IF V<=0 THEN 38\lF J<0 THEN 81
38 GOSUB 61\GOTO 31
41 PRINT "FUEL OUT AT"L "SEC "\S=(-V+SQR(V*V+2*A*G))/G\V=V+G*S\L=L+S
51 W=3600*V\PRINT"ON MOON AT"L"SEC - IMPACT VELOCITY" W "MPH"
52 IF W>1.2 THEN 53\PRINT "PERFECT LANDING! (LUCKY)"\GOTO 95
53 IF W>10 THEN 56\PRINT "GOOD LANDING (COULD BE BETTER)"\GOTO 95
56 IF W>60 THEN 58\PRINT "CRAFT DAMAGE... YOU'RE STRANDED HERE UNTIL"
57 PRINT "A RESCUE PARTY ARRIVES, HOPE YOU HAVE ENOUGH OXYGEN!"\GOTO 95
58 PRINT "SORRY, BUT THERE WERE NO SURVIVORS... YOU BLEW IT!"
59 PRINT "IN FACT, YOU BLASTED A NEW LUNAR CRATER"W*.2777"FT DEEP"
60 GOTO 95
61 L=L+S\T=T-S\M=M-S*K\A=I\V=J\RETURN
71 IF S<5E-3 THEN 51\D=V+SQR(V*V+2*A*(G-Z*K/M)\S=2*A/D
73 GOSUB 91\GOSUB 61\GOTO 71
81 W=(1-M*G/(Z*K))/2\S=M*V/(Z*K*(W+SQR(W*W+V/Z)))+.05\GOSUB 91
83 IF I<=0 THEN 71\GOSUB 61\IF J>0 THEN 31\IF V>0 THEN 81\GOTO 31
91 Q=S*K/M\J=V+G*S+Z*(-Q-Q*Q/2-Q^3/3-Q^4/4-Q^5/5)
94 I=A-G*S*S/2-V*S+Z*S*(Q/2+Q^2/6+Q^3/12+Q^4/20+Q^5/30)\RETURN
95 PRINT\PRINT\PRINT\PRINT "TRY AGAIN??"\GOTO 6
99 END

If you peruse the original code, you will see the quandary that I'm in. It is peppered with GOTOs and jumps as the result of IF THEN statements. Disentangling this has become somewhat of a mission for me.

I have figured out the way I want to do my version of this program. It is a simple falling body in a vacuum problem, so there are two conditions: Are you still above the ground? and Do you have any fuel left for your retro rockets? You must manage your descent using different rates of fuel consumption in order to arrive at the ground with fuel left, and pretty near zero downward velocity.

So I have the following code working for a falling body in a vacuum:
Code:

EXPORT Lander()
BEGIN
  PRINT();
  L:=0;       // ELAPSED TIME
  T:=10;      // SEC PER INTERVAL
  A:=120;     // MI
  V:=1;       // MI/S
  M:=33000;   // LB
  N:=16500;   // LB
  G:=1.6249;  // MOON G IN M/S^2

  PRINT("SEC : " +"MI+FT : " +"MPH : " +"LB_FUEL : " +"RATE : ");

  A:=A*1609.344; // CONVERT ALT TO METERS
  V:=V*1609.344; // CONVERT VEL TO M/S

  WHILE A>0 DO  // while not yet landed
    PRINT(L +" : " +IP(A/1609.344) +"+" +IP(5280*FP(A/1609.344)) +" : " +IP((3600*(V/1609.344))) +" : " +(M-N) +" : ");
    INPUT(R);   // GET BURN RATE

    IF M-N>R*T THEN  // if fuel left
      
      M:=M-(R*T);
    END;

    D:=(V*T+0.5*G*T^2);
    A:=A-D;
    V:=(V+G*T);
    L:=L+T;

  END;

  PRINT(L +" : " +IP(A/1609.344) +"+" +IP(5280*FP(A/1609.344)) +" : " +IP((3600*(V/1609.344))) +" : " +(M-N) +" : ");
END;

This code I have works perfectly like the sample run in the original book for the time that there is 0 as the input for the burn rate, so I figure that I have the falling body in a vacuum code in good shape.

Where I have been struggling for the past week, is to understand what the original author is doing to form the opposing vector made by the entry of the burn rate. It looks to me like the original code converts everything to increments of time somehow and computes distance and velocity from that? I'm pretty much stumped at this point.

If anyone cares to take a look at the code and offer me any suggestions on how to implement the retro rocket burn rate to slow the descent, I would greatly appreciate any thoughts you may have.

Thanks in advance!

smp
Find all posts by this user
Quote this message in a reply
08-18-2015, 08:34 AM (This post was last modified: 08-18-2015 08:41 AM by Martin Hepperle.)
Post: #2
RE: Rocket Game - from 101 BASIC Computer Games
In case you would also consider another implementation: Here is one I have written in VBA.
For testing, you can copy it into the VBA environment of a MS-Office application like Word, Excel, Powerpoint and run it there.
I think the code is pretty well structured and easy to understand.
You could more easily translate it to the Prime than your original BASIC code.

Note that the code contains a hardwired "autopilot", which must of course be removed for an interactive game.
The numeric values are arbitrary - I did not bother to look up realistic values e.g. for ther "Eagle".

Code:

Sub lander()

    '
    ' Simulation of a vertical descent to the moon
    '
    ' Based on analytical integration of equations
    ' of motion for variable mass
    '
    ' Martin Hepperle
    ' 2015
    
    ' all in metric units
    ' no resistance of air
    
    ' current time and time step
    Dim t, dt
    ' current altitude
    Dim h
    ' current speed
    Dim v
    ' current total mass
    Dim m
    ' fuel mass
    Dim mf
    ' specific fuel consumption of engine
    Dim SFC
    ' gravity acceleration
    Dim g
    ' engine thrust (commanded by pilots input)
    Dim Thrust
    ' count
    Dim i
    
    ' ===== set initial conditions
    ' time
    t = 0
    ' time step [s]
    dt = 0.25
    ' thrust (commanded by pilot)
    Thrust = 0#
    ' initial altitude (+=up)
    h = 100
    ' initial velocity of vehicle [kg] (+=up)
    v = 0
    ' initial mass of vehicle [kg]
    m = 1000
    ' fuel mass (part of m)
    mf = 46
    ' specific fuel consumption of propulsion unit [kg/N/s]
    ' SFC is the fuel mass per second burnt for one Newton of thrust
    SFC = 10 / 3600
    ' gravity acceleration [m/s^2]
    g = 1.225
    
    ' output initial state
    Debug.Print "t [s]" + vbTab + "H [m]" + vbTab + "m [kg]" + vbTab + "v [m/s]"
    Debug.Print FormatNumber(t, 2) + vbTab + FormatNumber(h, 2) + vbTab + FormatNumber(m, 2) + vbTab + FormatNumber(v, 1) + vbTab + FormatNumber(Thrust, 1)
    
    For i = 1 To 10000
        ' handle one time step with constant thrust
        
        ' here we could implement a control law (autopilot)
        If h < 0.5 Then
            ' feet are touching the ground
            Thrust = 0
        ElseIf h < 25 Then
            ' sort of toggle switch auto pilot
            ' floor it - if any fuel left
            If mf > 0 Then
                Thrust = 5400
            End If
        Else
            ' no thrust 
            Thrust = 0
        End If

        '
        ' what happens during this time step dt?
        '
        
        ' change of mass (negative: burning fuel)
        dm = -SFC * Thrust * dt
        
        ' change of velocity (momentum equation for variable mass analytically integrated over time)
        dv = -(g * dt) - 1 / SFC * Log(1 - Thrust * SFC * dt / m)
        
        ' change of height (momentum equation for variable mass analytically integrated over time)
        If Thrust < 0.000000000001 Then
            ' limit case of Thrust=0
            dh = (v - g * dt / 2) * dt
        Else
            ' general case id Thrust>0
            xx = Log(1 - SFC * Thrust * dt / m)
            dh = (((1 - xx) + (v - g / 2 * dt) * SFC) * dt + xx * m / (Thrust * SFC)) / SFC
        End If
    
        ' check height
        If -dh > h Then
            ' this step would lead below the surface
            ' reduce time step to refine approach
            dt = dt / 10#
            ' repeat this step with new dt
        Else
            ' update state
            m = m + dm
            mf = mf + dm
            v = v + dv
            h = h + dh
            t = t + dt
                   
            ' output current state
            Debug.Print FormatNumber(t, 4) + vbTab + FormatNumber(h, 2) + vbTab + FormatNumber(m, 2) + vbTab + FormatNumber(v, 1) + vbTab + FormatNumber(Thrust, 1)
            
            ' have a look at the fuel gauge
            If mf < 0.5 Then
                Debug.Print "Oh: running out of fuel"
                ' no more input allowed
            End If
            
            If h <= 0.0001 Then
                If v > -5 Then
                    Debug.Print "soft landing"
                Else
                    Debug.Print "Oops - your return ticket got lost somewhere"
                End If
                Debug.Print "fuel remaining: "; mf; " kg"
                Exit For
            End If
        End If
    Next i   

End Sub
Find all posts by this user
Quote this message in a reply
08-18-2015, 11:21 AM
Post: #3
RE: Rocket Game - from 101 BASIC Computer Games
(08-18-2015 08:34 AM)Martin Hepperle Wrote:  In case you would also consider another implementation: Here is one I have written in VBA.

Thanks very much for your reply, and for the alternative code, Martin!
This gives me something new to consider. I hope this helps me break out of my confusion.

smp
Find all posts by this user
Quote this message in a reply
08-18-2015, 12:14 PM
Post: #4
RE: Rocket Game - from 101 BASIC Computer Games
I was wondering how you were detecting the result of your most current burn rate? As provided the program seems to just show the input screen, until the "Lander" terminates successfully, or not.

However, if a "wait(R);" is used immediately after the INPUT(R); line, the corresponding output becomes viewable.

The details for making the program more interactive are more than I want to undertake, but you could make use of graphic commands (described in the user guide) to not only watch the lander progress, but influence the craft as it falls to the landing zone. That would allow you to more easily land the craft at very close to zero velocity, fairly gracefully.

Code:

EXPORT Lander()
BEGIN
  PRINT();
  L:=0;       // ELAPSED TIME
  T:=10;      // SEC PER INTERVAL
  A:=120;     // MI
  V:=1;       // MI/S
  M:=33000;   // Capsule Weight LB
  N:=16500;   // Fuel Weight LB
  G:=1.6249;  // MOON G IN M/S^2

  PRINT("SEC : " +"MI+FT : " +"MPH : " +"LB_FUEL : " +"RATE : ");

  A:=A*1609.344; // CONVERT ALT TO METERS
  V:=V*1609.344; // CONVERT VEL TO M/S

  WHILE A>0 DO  // while not yet landed
    PRINT(L +" : " +IP(A/1609.344) +"+" +IP(5280*FP(A/1609.344)) +" : " +IP((3600*(V/1609.344))) +" : " +(M-N) +" : ");
    INPUT(R);   // GET BURN RATE

    wait(R);    //  Result of current burn rate

    IF M-N>R*T THEN  // if fuel left      
      M:=M-(R*T);
    END;

    D:=(V*T+0.5*G*T^2);
    A:=A-D;
    V:=(V+G*T);
    L:=L+T;

  END;

  PRINT(L +" : " +IP(A/1609.344) +"+" +IP(5280*FP(A/1609.344)) +" : " +IP((3600*(V/1609.344))) +" : " +(M-N) +" : ");
END;
Find all posts by this user
Quote this message in a reply
08-18-2015, 12:30 PM
Post: #5
RE: Rocket Game - from 101 BASIC Computer Games
(08-18-2015 12:14 PM)DrD Wrote:  I was wondering how you were detecting the result of your most current burn rate? As provided the program seems to just show the input screen, until the "Lander" terminates successfully, or not.

Hi DrD,

Yes you are correct in your observation. At present, I am only attempting to get portions of the "simulation" to operate as they did in the original BASIC program. I believe that I've achieved that with the simple falling body in a vacuum code that I presented. I've been trying a variety of other bits of code to see if I can get the decelleration as a function of the burn rate to work anywhere near close to the original, but I have failed in this so far.

My intention is to get the mechanics to operate as they did in the original BASIC program, and then move on to learn about getting it to display well on the Prime. Once I get a good replica of the original, I also intend to attempt to learn more about the Prime's display capabilities and embellish the program as you suggest.

Thanks very much for your input. I greatly appreciate your assistance.

smp
Find all posts by this user
Quote this message in a reply
08-18-2015, 02:39 PM
Post: #6
RE: Rocket Game - from 101 BASIC Computer Games
(08-16-2015 04:39 PM)smp Wrote:  I am attempting to convert the old Rocket BASIC game (from 101 BASIC Computer Games by Digital Equipment Corporation) to run on my HP Prime calculator. I'm doing this as one of my exercises in learning to program on the HP Prime, and also to end up with one of the vintage games I love running on my calculator.

Here's the original BASIC code:
Code:

2 PRINT "THIS IS A COMPUTER SIMULATION OF AN APOLLO LUNAR"
3 PRINT "LANDING CAPSULE, "\PRINT\PRINT
4 PRINT "THE ON-BOARD COMPUTER HAS FAILED (IT WASN'T MADE BY"
5 PRINT "DIGITAL) SO YOU HAVE TO LAND THE CAPSULE MANUALLY"
6 PRINT\PRINT "SET BURN RATE OF RETRO ROCKETS TO ANY VALUE BETWEEN"
7 PRINT "0 (FREE FALL) AND 200 (MAXIMUM BURN) POUNDS PER SECOND"
8 PRINT "SET NEW BURN RATE EVERY 10 SECONDS. "\PRINT
9 PRINT "CAPSULE WEIGHT 32,500 LBS, FUEL WEIGHTT 16,500 LBS"
19 PRINT\PRINT\PRINT "GOOD LUCK!!!"
11 L=0
13 PRINT\PRINT "SEC", "MI + FT", "MPH", "LB FUEL", "BURN RATE"\PRINT
15 A=120\V=1\M=33000\N=16500\G=1E-3\Z=1.8
21 PRINT L,INT(A); INT(5280*(A-INT(A))),3600*V,M-N,\INPUT K\T=10
31 IF M-N<.001 THEN 41\IF T<.001 THEN 21\S=T\IF M>N+S*K THEN 35
32 S=(M-N)/K
35 GOSUB 91\IF I<=0 THEN 71\IF V<=0 THEN 30\lF J<0 THEN 81
38 GOSUB 61\GOTO 31
41 PRINT "FUEL OUT AT"L "SEC "\S=(-V+SQR(V*V+2*A*G))/G\V=V+G*S\L=L+S
51 W=3600*V\PRINT"ON MOON AT"L"SEC - IMPACT VELOCITY" W "MPH"
52 IF W>1.2 THEN 53\PRINT "PERFECT LANDING! (LUCKY)"\GOTO 95
53 IF W>10 THEN 56\PRINT "GOOD LANDING (COULD BE BETTER)"\GOTO 93
56 IF W>60 THEN 58\PRINT "CRAFT DAMAGE... YOU'RE STRANDED HERE UNTIL"
57 PRINT "A RESCUE PARTY ARRIVES, HOPE YOU HAVE ENOUGH OXYGEN!"\GOTO 95
58 PRINT "SORRY, BUT THERE WERE NO SURVIVORS... YOU BLEW IT!"
59 PRINT "IN FACT, YOU BLASTED A NEW LUNAR CRATER"W*.2777"FT DEEP"
60 GOTO 95
61 L=L+S\T=T-S\M=M-S*K\A=I\V=J\RETURN
71 IF S<5E-3 THEN 51\D=V+SQR(V*V+2*A*(G-Z*K/M)\S=2*A/D
73 GOSUB 91\GOSUB 61\GOTO 71
81 W=(1-M*G/(Z*K))/2\S=M*V/(Z*K*(W+SQR(W*W+V/Z)))+.05\GOSUB 91
83 IF I<=0 THEN 71\GOSUB 61\IF J>0 THEN 31\IF V>0 THEN 81\GOTO 31
91 Q=S*K/M\J=V+G*S+Z*(-Q-Q*Q/2-Q^3/3-Q^4/4-Q^5/5)
94 I=A-G*S*S/2-V*S+Z*S*(Q/2+Q^2/6+Q^3/12+Q^4/20+Q^5/30)\RETURN
95 PRINT\PRINT\PRINT\PRINT "TRY AGAIN??"\GOTO 6
99 END

If you peruse the original code, you will see the quandary that I'm in. It is peppered with GOTOs and jumps as the result of IF THEN statements. Disentangling this has become somewhat of a mission for me.

I have figured out the way I want to do my version of this program. It is a simple falling body in a vacuum problem, so there are two conditions: Are you still above the ground? and Do you have any fuel left for your retro rockets? You must manage your descent using different rates of fuel consumption in order to arrive at the ground with fuel left, and pretty near zero downward velocity.

So I have the following code working for a falling body in a vacuum:
Code:

EXPORT Lander()
BEGIN
  PRINT();
  L:=0;       // ELAPSED TIME
  T:=10;      // SEC PER INTERVAL
  A:=120;     // MI
  V:=1;       // MI/S
  M:=33000;   // LB
  N:=16500;   // LB
  G:=1.6249;  // MOON G IN M/S^2

  PRINT("SEC : " +"MI+FT : " +"MPH : " +"LB_FUEL : " +"RATE : ");

  A:=A*1609.344; // CONVERT ALT TO METERS
  V:=V*1609.344; // CONVERT VEL TO M/S

  WHILE A>0 DO  // while not yet landed
    PRINT(L +" : " +IP(A/1609.344) +"+" +IP(5280*FP(A/1609.344)) +" : " +IP((3600*(V/1609.344))) +" : " +(M-N) +" : ");
    INPUT(R);   // GET BURN RATE

    IF M-N>R*T THEN  // if fuel left
      
      M:=M-(R*T);
    END;

    D:=(V*T+0.5*G*T^2);
    A:=A-D;
    V:=(V+G*T);
    L:=L+T;

  END;

  PRINT(L +" : " +IP(A/1609.344) +"+" +IP(5280*FP(A/1609.344)) +" : " +IP((3600*(V/1609.344))) +" : " +(M-N) +" : ");
END;

This code I have works perfectly like the sample run in the original book for the time that there is 0 as the input for the burn rate, so I figure that I have the falling body in a vacuum code in good shape.

Where I have been struggling for the past week, is to understand what the original author is doing to form the opposing vector made by the entry of the burn rate. It looks to me like the original code converts everything to increments of time somehow and computes distance and velocity from that? I'm pretty much stumped at this point.

If anyone cares to take a look at the code and offer me any suggestions on how to implement the retro rocket burn rate to slow the descent, I would greatly appreciate any thoughts you may have.

Thanks in advance!

smp

Would the version in the microcomputer edition of 101 BASIC Games help? This was written by Ahl after the original DEC version. The programs were converted from DEC Basic Plus to run in 8K Altair (Microsoft BASIC)

Code:

10 PRINT TAB(30); "ROCKET"
20 PRINT TAB(15); "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY"
30 PRINT: PRINT: PRINT
70 PRINT "LUNAR LANDING SIMULATION"
80 PRINT "----- ------- ----------": PRINT
100 INPUT "DO YOU WANT INSTRUCTIONS (YES OR NO)"; A$
110 IF A$ = "NO" THEN 390
160 PRINT
200 PRINT "YOU ARE LANDING ON THE MOON AND AND HAVE TAKEN OVER MANUAL"
210 PRINT "CONTROL 1000 FEET ABOVE A GOOD LANDING SPOT. YOU HAVE A DOWN-"
220 PRINT "WARD VELOCITY OF 50 FEET/SEC. 150 UNITS OF FUEL REMAIN."
225 PRINT
230 PRINT "HERE ARE THE RULES THAT GOVERN YOUR APOLLO SPACE-CRAFT:": PRINT
240 PRINT "(1) AFTER EACH SECOND THE HEIGHT, VELOCITY, AND REMAINING FUEL"
250 PRINT "    WILL BE REPORTED VIA DIGBY YOUR ON-BOARD COMPUTER."
260 PRINT "(2) AFTER THE REPORT A '?' WILL APPEAR. ENTER THE NUMBER"
270 PRINT "    OF UNITS OF FUEL YOU WISH TO BURN DURING THE NEXT"
280 PRINT "    SECOND. EACH UNIT OF FUEL WILL SLOW YOUR DESCENT BY"
290 PRINT "    1 FOOT/SEC."
310 PRINT "(3) THE MAXIMUM THRUST OF YOUR ENGINE IS 30 FEET/SEC/SEC"
320 PRINT "    OR 30 UNITS OF FUEL PER SECOND."
330 PRINT "(4) WHEN YOU CONTACT THE LUNAR SURFACE. YOUR DESCENT ENGINE"
340 PRINT "    WILL AUTOMATICALLY SHUT DOWN AND YOU WILL BE GIVEN A"
350 PRINT "    REPORT OF YOUR LANDING SPEED AND REMAINING FUEL."
360 PRINT "(5) IF YOU RUN OUT OF FUEL THE '?' WILL NO LONGER APPEAR"
370 PRINT "    BUT YOUR SECOND BY SECOND REPORT WILL CONTINUE UNTIL"
380 PRINT "    YOU CONTACT THE LUNAR SURFACE.": PRINT
390 PRINT "BEGINNING LANDING PROCEDURE..........": PRINT
400 PRINT "G O O D  L U C K ! ! !"
420 PRINT: PRINT
430 PRINT "SEC  FEET      SPEED     FUEL     PLOT OF DISTANCE"
450 PRINT
455 T = 0: H = 1000: V = 50: F = 150
490 PRINT T; TAB(6); H; TAB(16); V; TAB(26); F; TAB(35); "I"; TAB(H / 15); "*"
500 INPUT B
510 IF B < 0 THEN 650
520 IF B > 30 THEN B = 30
530 IF B > F THEN B = F
540 V1 = V - B + 5
560 F = F - B
570 H = H - .5 * (V + V1)
580 IF H <= 0 THEN 670
590 T = T + 1
600 V = V1
610 IF F > 0 THEN 490
615 IF B = 0 THEN 640
620 PRINT "**** OUT OF FUEL ****"
640 PRINT T; TAB(4); H; TAB(12); V; TAB(20); F; TAB(29); "I"; TAB(H / 12 + 29); "*"
650 B = 0
660 GOTO 540
670 PRINT "***** CONTACT *****"
680 H = H + .5 * (V1 + V)
690 IF B = 5 THEN 720
700 D = (-V + SQR(V * V + H * (10 - 2 * B))) / (5 - B)
710 GOTO 730
720 D = H / V
730 V1 = V + (5 - B) * D
760 PRINT "TOUCHDOWN AT"; T + D; "SECONDS."
770 PRINT "LANDING VELOCITY="; V1; "FEET/SEC."
780 PRINT F; "UNITS OF FUEL REMAINING."
790 IF V1 <> 0 THEN 810
800 PRINT "CONGRATULATIONS! A PERFECT LANDING!!"
805 PRINT "YOUR LICENSE WILL BE RENEWED.......LATER."
810 IF ABS(V1) < 2 THEN 840
820 PRINT "***** SORRY, BUT YOU BLEW IT!!!!"
830 PRINT "APPROPRIATE CONDOLENCES WILL BE SENT TO YOUR NEXT OF KIN."
840 PRINT: PRINT: PRINT
850 INPUT "ANOTHER MISSION"; A$
860 IF A$ = "YES" THEN 390
870 PRINT: PRINT "CONTROL OUT.": PRINT
999 END

Tom L
My wife's judgement is much better than mine.
Look who we each married!
Find all posts by this user
Quote this message in a reply
08-18-2015, 04:06 PM
Post: #7
RE: Rocket Game - from 101 BASIC Computer Games
(08-18-2015 02:39 PM)toml_12953 Wrote:  Would the version in the microcomputer edition of 101 BASIC Games help? This was written by Ahl after the original DEC version. The programs were converted from DEC Basic Plus to run in 8K Altair (Microsoft BASIC)

Hi Tom,

Thanks very much for this code! It appears that Mr. Ahl changed a number of things from the original, but these directions offer much more insight into how the numbers are supposed to work out, and the calculations seem much more simplified. I'll take a look at this new (to me) code and see what I can make of it.

smp
Find all posts by this user
Quote this message in a reply
08-31-2015, 09:43 AM (This post was last modified: 09-01-2015 06:57 AM by Martin Hepperle.)
Post: #8
RE: Rocket Game - from 101 BASIC Computer Games
... and here is a translation of the VBA code to the Prime
... TODO: add a graphical user interface

I think, sometimes it is better to start over from scratch instead of trying to convert "old spagheti" to "cuisine nouvelle".

Code:

//
// Simulation of a vertical descent to a planet
//
// Based on analytical integration of equations
// of motion for variable mass
//
// Martin Hepperle
// 2015

// forward declarations
ShowState (t,h,mf,v,Thrust);

EXPORT Lander()
BEGIN
   
   // metric units
   // no resistance of air
   // no lateral motion
   // no graphics
    
   // current time and time step
   LOCAL t, dt;
   // current altitude
   LOCAL h, dh;
   // current speed
   LOCAL v, dv;
   // current total mass
   LOCAL m, dm;
   // fuel mass
   LOCAL mf;
   // specific fuel consumption of engine
   LOCAL SFC;
   // gravity acceleration
   LOCAL g;
   // engine thrust (commanded by pilots input)
   LOCAL Thrust;
   // count
   LOCAL i, xx;

   // ===== set initial conditions
   // time
   t := 0;
   // time step [s]
   dt := 0.25;
   // thrust (commanded by pilot)
   Thrust := 0;
   // initial altitude (+=up)
   h := 100;
   // initial velocity of vehicle [kg] (+=up)
   v := 0;
   // initial mass of vehicle [kg]
   m := 1000;
   // fuel mass (part of m)
   mf := 46;
   // specific fuel consumption of propulsion unit [kg/N/s]
   // SFC is the fuel mass per second burnt for one Newton of thrust
   SFC := 10 / 3600;
   // gravity acceleration [m/s^2]
   g := 1.225;

   RECT_P (0,0,400,200,0,0);

   // output initial state
   TEXTOUT_P( "t [s]" + "     " + "H [m]" + "     " + "mf [kg]" + "     " + "v [m/s]"+ "     " + "T [N]",
              10,40,4,#FFFFFF,400,#000000);
   ShowState (t,h,mf,v,Thrust);

   FOR i FROM 1 TO 30000 DO
      // handle one time step with constant thrust
      WAIT(0.1);
   
      IF mf > 0.0 THEN
         IF ISKEYDOWN(2) THEN
            Thrust:=Thrust+250; 
         ELSE
            IF ISKEYDOWN(12) THEN
               Thrust:=Thrust-250; 
            END;
         END;
      ELSE
         Thrust:=0; 
      END;
        
      // here we could implement a control law (autopilot)
      IF h < 0.5 THEN
         // feet sensors (0.5 meters below the lander)
         // are touching the ground
         Thrust := 0
      END;

      //
      // what happens during this time step dt?
      //
        
      // change of mass (negative: burning fuel)
      dm := -SFC * Thrust * dt;
        
      // change of velocity (momentum equation for variable mass 
      // analytically integrated over time)
      dv := -(g * dt) - 1 / SFC * LN(1 - Thrust * SFC * dt / m);
        
      // change of height (momentum equation for variable mass
      // analytically integrated over time)
      IF Thrust < 0.000000000001 THEN
         // limit case: Thrust=0
         dh := (v - g * dt / 2) * dt;
      ELSE
         // general case: Thrust>0
         xx := LN(1 - SFC * Thrust * dt / m);
         dh := ((1 - xx) / SFC + v - g / 2 * dt) * dt + xx * m /
                                                 (Thrust * SFC * SFC);
      END;
    
      // check height and fuel
      IF h < -dh THEN
         dh := -h;
      END;

      IF mf < -dm THEN
         dm := -mf;
      END;

      // update state
      m := m + dm;
      mf := mf + dm;
      v := v + dv;
      h := h + dh;
      t := t + dt;
                   
      // output current state
      ShowState (t,h,mf,v,Thrust);
        
      IF h <= 0.01 THEN
         IF v > -5 THEN
            TEXTOUT_P("soft landing",
                      10,125,4,#DDFFDD,400,#000000);
         ELSE
            TEXTOUT_P("you broke: landing gear, your spine",
                      10,125,4,#FFFFFF,400,#000000);
         END;
         TEXTOUT_P("fuel remaining: " + STRING(mf,2,1) + " kg",
                   10,90,4,#FFFFFF,400,#000000);
         BREAK; // FOR
      END;

   END; // FOR

   // output final state
   ShowState (t,h,mf,v,Thrust);

   FREEZE;
   
   return 0;

END;

// show the current state vector of the vehicle motion
ShowState (t,h,mf,v,Thrust)
BEGIN
   RECT_P (10,70,300,90,0,0);
   TEXTOUT_P(STRING(t,2,2),      10,70,4,#FFFFFF,500,#000000);
   TEXTOUT_P(STRING(h,2,1),      70,70,4,#FFFFFF,500,#000000);
   TEXTOUT_P(STRING(mf,2,1),    130,70,4,#FFFFFF,500,#000000);
   TEXTOUT_P(STRING(v,2,1),     190,70,4,#FFFFFF,500,#000000);
   TEXTOUT_P(STRING(Thrust,2,0),250,70,4,#FFFFFF,500,#000000);

   // have a look at the fuel gauge
   IF mf < 1.0 THEN
      TEXTOUT_P(" FUEL! ",   10,150,5,#FFFF00,100,#FF0000);
   END;

END;
Find all posts by this user
Quote this message in a reply
08-31-2015, 11:32 AM
Post: #9
RE: Rocket Game - from 101 BASIC Computer Games
(08-31-2015 09:43 AM)Martin Hepperle Wrote:  ... and here is a translation of the VBA code to the Prime
... TODO: add a graphical user interface

Hi Martin,

Thank you *very* much for this code. I will study it, as I continue on my learning path for programming my HP Prime.

smp
Find all posts by this user
Quote this message in a reply
12-31-2018, 09:13 AM
Post: #10
RE: Rocket Game - from 101 BASIC Computer Games
Hi,

Well, I'd say the program was compressed before being published; that's why it's rather hard to read.
In a somewhat less compact version it would look more like this. (Slightly different dialect, for readability.)

Code:

10 rem ROCKET GAME
100 rem Intro:
110 PRINT "THIS IS A COMPUTER SIMULATION OF AN APOLLO LUNAR"
120 PRINT "LANDING CAPSULE, ":PRINT:PRINT
130 PRINT "THE ON-BOARD COMPUTER HAS FAILED (IT WASN'T MADE BY"
140 PRINT "DIGITAL) SO YOU HAVE TO LAND THE CAPSULE MANUALLY"
199 rem -----------------------------------------------------------
200 rem Program Loop:
299 rem -----------------------------------------------------------
300 rem Instructions:
310 PRINT
320 PRINT "SET BURN RATE OF RETRO ROCKETS TO ANY VALUE BETWEEN"
330 PRINT "0 (FREE FALL) AND 200 (MAXIMUM BURN) POUNDS PER SECOND"
340 PRINT "SET NEW BURN RATE EVERY 10 SECONDS. "
350 PRINT
360 PRINT "CAPSULE WEIGHT 32,500 LBS, FUEL WEIGHT 16,500 LBS"
370 PRINT:PRINT
371 PRINT "GOOD LUCK!!!"
380 goto 1000: Rem Game proper
499 rem -----------------------------------------------------------
500 rem Restart:
510 PRINT:PRINT:PRINT
520 PRINT "TRY AGAIN??"
521 rem This is not actually a question.
522 rem Rather, it's an order: There is no in-game way to stop.
530 GOTO 200: rem start of program loop
540 rem End of Program loop
998 rem -----------------------------------------------------------
999 rem -----------------------------------------------------------
1000 rem Game proper:
1010 L=0: Rem Time elapsed, in seconds
1020 PRINT
1021 PRINT "SEC", "MI + FT", "MPH", "LB FUEL", "BURN RATE":PRINT
1022 rem Could be made to repeat this header before it disappears.
1030 A=120: Rem Distance from Moon, in miles
1031 V=1: Rem Velocity, in miles per second
1032 M=33000: Rem Total weight, in pounds
1033 N=16500: Rem Non-fuel weight (capsule plus you), in pounds
1034 G=1E-3: rem Gravitational acceleration
1035 Z=1.8
1038 rem -----------------------------------------------------------
1039 rem Start of Game Loop:
1040 PRINT L,INT(A); INT(5280*(A-INT(A))),3600*V,M-N,
1041 INPUT K: Rem Burn Rate: Fills-in the last column of the table.
1042 T=10: Rem seconds till next input.
1059 rem -----------------------------------------------------------
1060 rem Start of Inner loop:
1070 IF M-N<0.001 THEN 2200: rem out of fuel
1071 IF T<0.001 THEN 1105: rem end of the game loop.
1072 S=T
1073 IF M <= N+S*K THEN S=(M-N)/K
1090 GOSUB 3200: rem calculate
1091 IF I<=0 THEN 1710
1092 IF V>0 and J<0 THEN 1110
1100 GOSUB 3100: rem update
1101 GOTO 1060: rem start of the inner loop
1102 rem End of inner loop
1103 rem -----------------------------------------------------------
1105 goto 1040: rem start of the game loop.
1110 rem End of Game loop.
1111 rem -----------------------------------------------------------
1999 rem -----------------------------------------------------------
2000 rem Routines
2099 rem -----------------------------------------------------------
2100 rem Endings
2199 rem -----------------------------------------------------------
2200 rem Out of Fuel:
2210 PRINT "FUEL OUT AT"L "SEC "
2211 S=(-V+SQR(V*V+2*A*G))/G
2212 V=V+G*S
2213 L=L+S
2299 rem -----------------------------------------------------------
2300 rem Arrival:
2310 W=3600*V
2311 PRINT"ON MOON AT"L"SEC - IMPACT VELOCITY" W "MPH"
2320 IF W>1.2 THEN 2330
2321 PRINT "PERFECT LANDING! (LUCKY)"
2322 GOTO 2380: rem end of arrival
2330 IF W>10 THEN 2340
2331 PRINT "GOOD LANDING (COULD BE BETTER)"
2332 GOTO 2380: rem end of arrival
2340 IF W>60 THEN 2360
2341 PRINT "CRAFT DAMAGE... YOU'RE STRANDED HERE UNTIL"
2350 PRINT "A RESCUE PARTY ARRIVES, HOPE YOU HAVE ENOUGH OXYGEN!"
2351 GOTO 2380: rem end of arrival
2360 PRINT "SORRY, BUT THERE WERE NO SURVIVORS... YOU BLEW IT!"
2370 PRINT "IN FACT, YOU BLASTED A NEW LUNAR CRATER"W*0.2777"FT DEEP"
2380 GOTO 500: rem restart
2380 rem End of arrival
2399 rem -----------------------------------------------------------
2499 rem -----------------------------------------------------------
2500 rem jumping point
2510 W=(1-M*G/(Z*K))/2
2520 S=M*V/(Z*K*(W+SQR(W*W+V/Z)))+0.05
2530 GOSUB 3200: rem calculate
2540 IF I>0 THEN 2700: rem loop 2
2550 rem Loop 1
2555 rem Once we get here, we're looping until arrival.
2560 IF S<5E-3 THEN 2300: rem arrival
2570 D=V+SQR(V*V+2*A*(G-Z*K/M)
2580 S=2*A/D
2580 GOSUB 3200: rem calculate
2590 GOSUB 3100: rem update
2600 GOTO 2550: rem Loop 1
2699 rem -----------------------------------------------------------
2700 Rem Loop 2
2710 GOSUB 3100
2720 IF J<=0 and V>0 THEN 2700: Rem loop 2
2730 GOTO 1060: rem inner loop
2998 rem -----------------------------------------------------------
2999 rem -----------------------------------------------------------
3000 rem Subroutines:
3099 rem -----------------------------------------------------------
3100 rem Update
3110 L=L+S:T=T-S:M=M-S*K:A=I:V=J:RETURN
3199 rem -----------------------------------------------------------
3200 rem Calculate
3210 Q=S*K/M:J=V+G*S+Z*(-Q-Q*Q/2-Q^3/3-Q^4/4-Q^5/5)
3220 I=A-G*S*S/2-V*S+Z*S*(Q/2+Q^2/6+Q^3/12+Q^4/20+Q^5/30):RETURN
3999 rem -----------------------------------------------------------
4000 rem Comments
4010 rem The game could be made to allow SI units, rather than Imperial.
4020 rem Could have a setting for exact old behaviour versus Digital ad-less.
4030 rem Could be modified to a lander for any vacuum atmosphere body.
Usual warnings apply.

(Doesn't immediately tell us what it does, but might make it easier to determine where to look.)

BFN,
Mysha
Find all posts by this user
Quote this message in a reply
12-31-2018, 07:16 PM
Post: #11
RE: Rocket Game - from 101 BASIC Computer Games
I don't know if this will help but the Linar Lander game published by HP for the HP-25 has a nice description of the math involved. I played this game so much in the 70's before I wrote a version in BASIC (with "graphics") for my Ohio Scientific C1P microcomputer.
Only 46 lines of code (instructions) in this version.
http://www.hpmuseum.org/software/25moonld.htm
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)