From: bbwwbb@mixcom.COM (Kevin Jessup)
Newsgroups: comp.sources.hp48
Subject: v01i013:  astronut11 - AstroNUT v1.1:  a lunar lander simulation, Part01/01
Date: 12 Aug 91 04:05:57 GMT
Followup-To: comp.sys.hp48

Checksum: 3957996941 (verify with brik -cv)
Submitted-by: Kevin Jessup <bbwwbb@mixcom.COM>
Posting-number: Volume 1, Issue 13
Archive-name: astronut11/part01

BEGIN_DOC astronut.doc

 AstroNUT V1.1
 by Kevin Jessup
 16-May-1991
 Submitted to comp.sources.hp48 on August 6th, 1991

 Version 1.1
 -----------
 This version adds a bit of audio and corrects a minor bug:
 flag -19, the COMPLEX MODE flag, is now cleared to insure
 that 2-d vectors are produced when required.  Also, all
 temporary global variables are cleared from the directory
 at the end of play.  (Please allow time for cleanup when
 the game ends: wait for the HP48SX busy indicator to shut
 off.)  Otherwise, the game is the same.

 Introduction
 ------------
 AstroNUT is a lunar lander simulation for the 48SX.
 It supports 2-d travel (up, down, left, right) and a
 random terraine that is generated for each new game.
 All routines are in RPL so the screen updates are somewhat
 slow.  I still find play acceptable however.

 The object of the game is to land on a more or less flat
 portion of the lunar surface with a horizontal velocity of
 zero and a vertical velocity of less than 5 feet per second.
 (Somewhat fast! Change it if you like.)  You have a limited
 amount of fuel available to do this.

 Initial parameters
 ------------------
 Altitude:            170 feet

 Vertical velocity:   -20 feet per second.  A "second" is
                      not the usual unit of time that you
                      are familiar with but how long it takes
                      this game to execute it's main loop!
                      You will have to hit the thrust key
                      quite often to slow down.  Read on...

 Horizontal velocity: 5 feet per second.  The direction
                      (left or right) is random.  The initial
                      horizontal position is also random.

 Fuel:                100 units.  In gallons, liters, cubic
                      light-years or whatever you'd like to
                      call it :-)

 Control keys
 ------------
 8: Apply upward thrust (One push equals thrust of 1/2 g)

 4: Apply left thrust (Changes horizontal vel. by 1 ft/sec)

 6: Apply right thrust (Changes horizontal vel. by 1 ft/sec)

 With each screen update, your downward velocity will
 increase due to the acceleration of gravity at a rate of
 4 ft/s^2.  It will require 2 hits of the vertical thrust
 (key 8) to exactly compensate for the acceleration due to
 gravity.

 Screen positioning
 ------------------
 As you move to the left and right edges of the display, you
 will wrap around to the opposite side.  There are "unlimited"
 vertical screens.  You will wrap around at the top and bottom.
 When you reach the lowest screen, there will be a slight pause
 as the lunar surface is drawn.  If you move above the lowest
 screen, the surface will be erased.  The current "flight
 parameters" are displayed at the top right of the LCD.

 Loading
 -------
 For the neophytes, those funny litle characters at the start
 of these lines are HP48SX comment delimiters.  You can transfer
 this entire file AS IS to your 48.  The 48 will remove all the
 comments and load only the code.

 After transferring this file to your 48, recall the directory
 to the stack.  Execute the BYTES command.  You should get the
 following...

              Level 2:    #5AB1h
              Level 1:    2707.5

 Once you have successfully transferred the directory to your 48,
 just hit PLAY to start.

 Be patient...after a little practice, you should be able to
 land using only 100 units of fuel.  You can modify the amount
 of fuel, thrust and acceleration due to gravity if you like.
 Study the code below to find out how.  Have fun!

 This is "freeware" but if you'd like to send a few bucks, don't
 let that stop you!

 Kevin Jessup
 9118 N 85th
 Milwaukee, WI 53224
 Email address: bbwwbb@mixcom.com

END_DOC

BYTES: #5AB1h   2720

BEGIN_RPL astronut
%%HP: T(3)A(R)F(.);

DIR                   @ AstroNUT directory

  PLAY                @ push PLAY to start
    \<< RCLF 3 FIX    @ save flags
-19 CF # 83h # 40h    @ create a blank PICT
BLANK PICT STO 1 CF   @ clear the crash flag
170 'ht' STO          @ set height to 170 feet
-20 'v' STO 5         @ set vertical v to -20
      IF RAND .5 <    @ set horiz v to 5 or -5
      THEN NEG
      END 'hv' STO
RAND 80 * IP 'x'      @ random horiz position
STO 100 'fuel' STO    @ 100 unit of fuel
2 CF                  @ clear the bottom flag
MAKBOTTOM { # 0h      @ random terrain coordinates
# 0h } PVIEW MAIN     @ display and loop on main
CRASHht 'ht' STO      @ display landing parameters
CRASHx 'x' STO
CRASHv 'v' STO
STATUS PICT NEWC      @ display landing position
SHIP GXOR PICT {      @ display AstroNUT or CRASH
# 5h # 5h }
      IF CRASHv -4    @ test slope, vv and hv
< CRASHsl ABS .084
> OR hv OR
      THEN
"*CRASH*" LOOSE
      ELSE PICT 7
'ht' STO+ 1 'x'
STO+ NEWC aflag REPL
"AstroNUT" WIN
      END 3 \->GROB
REPL 7 FREEZE         @ freeze the display
globals PURGE         @ purge temporary globals
      WHILE KEY       @ flush any excess keys
      REPEAT DROP
      END STOF        @ restore flags and quit
    \>>

  WIN                 @ Play the WIN tune.
    \<< 125           @ "I am not a musician!"
      DO DUP .02
BEEP 2 *
      UNTIL DUP
4000 >
      END DROP
    \>>

  LOOSE               @ Play the LOOSE tune
    \<< 4000
      DO DUP .02
BEEP 2 /
      UNTIL DUP 125
<
      END DROP
    \>>

  MAIN                @ main processing loop
    \<<
      DO              @ draw or erase the terraine
        IF ht 56 >
        THEN
          IF 2 FS?
          THEN
ERASE 2 CF
          END
        ELSE
          IF 2 FC?
          THEN
DRAWBOTTOM 2 SF
          END
        END STATUS    @ display flight parameters
NEWC PICT OVER SHIP   @ display the lander
GXOR ht 20 * .01      @ beep based on altitude
BEEP v 'ht' STO+ hv   @ calculate new position
'x' STO+               
        IF x 124 >    @ wrap horizontal
x 0 < OR
        THEN x 125
MOD ABS 'x' STO
        END
CHKBOTTOM GETKEY ag   @ see if we crashed, process keys
'v' STO+ PICT SWAP    @ acceleration increases v
SHIP GXOR             @ erase old position
      UNTIL 1 FS?     @ quit if we landed or crashed
      END
    \>>

@ CHKBOTTOM is the routine that eats all the CPU time.
@ If anyone knows how to speed it up, please do so.
@ It works by calculating linear regressions and then
@ comparing the line slopes.

  CHKBOTTOM           @ set flag 1 if we crashed
    \<< 1 botCOORDS   @ get terraine coordinates list size
SIZE 1 -
      FOR i           @ test each line segment
botCOORDS i GETI 3    @ get line endpoints
ROLLD GET DUP2 1      @ duplicate them
GET SWAP 1 GET        @ get the x coordinates and
        IF x 3 + \<=  @ see if lander is between them
SWAP x 3 + > AND
        THEN OVER     @ if so, compare line slopes
C\->V2 CL\GS \GS+ C\->V2 \GS+ @ calculate line slope
LR x DUP 'CRASHx'     @ calculate and save possible
STO 3 + PREDY         @ crash x and y positions
'CRASHht' STO SWAP
DROP DUP 'CRASHsl'    @ save crash slope
STO SWAP C\->V2 CL\GS @ calculate slope of line to
\GS+ x 3.001 + ht \->V2 @ the landers coordinates
\GS+ LR SWAP DROP
          IF \>=      @ if line segment slope >= the
          THEN 1 SF   @ slope of line to lander,
 v                    @ we crahed.  Set crash flag.
'CRASHv' STO 99 'i'   @ save crash velocity
STO
          END
        ELSE DROP2    @ not within this line segment
        END
      NEXT            @ check next line
    \>>

  MAKBOTTOM           @ generates a list of coordinates
    \<< { } 0 120     @ get an empty list
      FOR a a RAND    @ generate a random y coordinate
25 * IP 6 + 2 \->LIST
1 \->LIST + 12        @ save xy in list, do next
      STEP 130 OVER   @ line up the end points so
1 GET OBJ\-> DROP     @ we don't impact on wrap
SWAP DROP 2 \->LIST 1
\->LIST + 9 RAND * IP @ insure at least one flat line
2 + GETI 2 GET 3
ROLLD GETI 2 5 ROLL
PUT SWAP 1 - SWAP
PUT 'botCOORDS' STO   @ save the list
    \>>

  DRAWBOTTOM          @ maps terraine coordinates to
    \<< 1 botCOORDS   @ screen and display the lines
SIZE 1 -
      FOR i
botCOORDS i GETI
OBJ\-> ROT R\->B ROT 63
SWAP - R\->B ROT
\->LIST 3 ROLLD GET
OBJ\-> ROT R\->B ROT 63
SWAP - R\->B ROT
\->LIST LINE
      NEXT
    \>>

  STATUS              @ displays the flight parameters
    \<<
      \<< + 1 \->GROB
PICT 3 ROLLD REPL
      \>> \-> s
      \<< { # 54h
# 0h } "Height: "
ht s EVAL { # 54h
# 6h } "VertV:  " v
s EVAL { # 54h # Ch
} "HorizV: " hv s
EVAL { # 54h # 12h
} "Fuel:   " fuel s
EVAL
      \>>
    \>>

  GETKEY              @ processes keys
    \<<
      WHILE KEY
      REPEAT
        IF fuel 0 >   @ but only if we got fuel!
        THEN
          CASE DUP
72 ==
            THEN -1
'hv' STO+ -1 'fuel'
STO+
            END DUP
74 ==
            THEN 1
'hv' STO+ -1 'fuel'
STO+
            END DUP
63 ==
            THEN
thrust DUP NEG
'fuel' STO+ 'v'
STO+
            END
          END
        END DROP
      END
    \>>

  NEWC         @ get current screen coordiantes
    \<< x R\->B 57 1 ht
57 MOD 57 / - * R\->B
2 \->LIST
    \>>

  C\->V2       @ convert 2-element list to vector
    \<< OBJ\-> DROP \->V2
    \>>

  SHIP         @ GROB of the lander
GROB 6 6 E13333E11212

  aflag        @ GROB of a flag
GROB 7 7 F7747414F71010

  thrust 2     @ vertical thrust = -1/2 ag

  ag -4        @ acceleration due to gravity

  globals { \GSDAT     @ these are PURGEd
CRASHv CRASHsl
CRASHht CRASHx \GSPAR
botCOORDS fuel x hv
v ht }

END

@ END OF ASCII FILE
END_RPL


---------------------------------------------------------------------------- 
  Kevin Jessup, software engineer         bbwwbb@mixcom.com
  marquette electronics                   (414)362-2020
  Milwaukee, WI 

