Post by B+ on Mar 7, 2020 4:51:46 GMT
Here it is again!
And if you want to try and land it yourself toggle auto-pilot with key "a" and use left, right and up arrow keys.
If you are sure you are going to crash then hit "g" and pray!
'Lander mod Auto mode.txt for JB v2 B+ post 2018-11-29
' 2018-11-26 build from Lander mod 2.txt for JB v2 B+ 2018-05-29
' which was built from:
' Lander by Carl mod Rod mod B+.bas for JB v2 started 2018-05-26
' from Rod's mod of Lander.bas written by Carl Gundel
' carlg@world.std.com
' Needs at least Liberty BASIC v2.0 ????
' This file is contributed to the public domain
'
' Development Notes:
' 2018-11-26 fix code and comment better, fix error /crash when lander beyond LANDY limits
' fix left arrow when VDA goes below 0
' HAL code started with slow downs of DX and DY dropping and keeping upright
' 2018-11-27 Post report the crashing problem after a 2 - 21 rounds played.
' 2018-11-27 HAL now does Landing zone spotting and targeting now, pretty close!
' 2018-11-28 add God mod, press g so wont crash but wont get credit for Landing either
' 2018-11-29 simplfied drop code in AUTO = 2 section of HAL backed up again in God mod copy
' 2018-11-29 attempt to add nudge code
' 2018-11-29 found error in target x middle calculation, added yellow circle to spot VX + 15 and VY + 24
' 2018-11-29 one window, new colors, fuel gage horizontal now. Almost pinpoint landings most times.
' 2018-11-30 comment out flush as per Rod (and Carl earlier now that I remember!)
' 2018-11-30 put timer 0 at start out of IF block.
' 2018-11-30 back to branch labels for main code and timer.
' 2018-12-01 back to sub's using Rod's work around for timer.
' 2018-12-01 working and added drifts label (if start game with AUTO set at 1 get many drifts off screen
' 2018-12-01 rework all this code for calculating with VX the middle bottom of craft when up right
'
' ======================== INSTRUCTIONS ============================
'
' Objective: You must make a VERY gentle and level landing on one of
' the flat areas with Lander in upright angle!
'
' Use the left or right arrow keys to rotate lander left or right
' Use the up arrow for forward Thrust
' NEW HERE! Use the "a" key to toggle auto pilot on and off
'
'===================================================================
' globals all caps for easier code reading
' note: D stands for Delta the nerdy way to say change
' CONSTANTS
global XMAX, YMAX, PI, D2R, DG
XMAX = 800 'width drawing area needed
YMAX = 600 'height of drawing area
PI = acs(-1) 'constant pi
D2R = PI / 180 'convert angle in degrees to radians
DG = .1 'this is the constant change in vertical speed due to gravity
' GLOBAL VARIABLES for the subs
dim LANDY(XMAX), LZX(15), LZY(15) 'array tracks y heights of land across the screen (x)
global FUEL, SPEED, VDA, VX, VY, DX, DY 'for locating the Lander commented in [startGame]
global LZI, AUTO, TARGET, BYE 'for toggle of Auto Pilot or quit game
global SUCCESS, FUEL0, LEVEL0, TILTS, OTHER 'how round ends success or crash type
nomainwin
WindowWidth = XMAX + 8
WindowHeight = YMAX + 32
UpperLeftX = int((DisplayWidth-WindowWidth)/2)
UpperLeftY = int((DisplayHeight-WindowHeight)/2)
graphicbox #lander.fuel 150, YMAX - 60, 500, 20
open "Lunar Lander with Auto Pilot Toggle (key a), quit (q)" for graphics_nsb as #lander
#lander "trapclose quit" ' set end program code
#lander "when characterInput control" ' set keypress code
#lander "setfocus" ' catch keypresses see sub control
call makeSprites 'this sets up the lander image
call startGame
wait
sub startGame ' (re)initialize redraw and reset setting and game variables
LZI = 0 ' track landing zone index
call setBackground 'make landing scene and record surface heights of land in LANDY()
#lander "spritexy lem 50 50"
#lander.fuel "down ; fill red ; size 9 ; north ; turn 90 ; color darkgreen"
FUEL = 500 ' this is the space vehicle's fuel
SPEED = 6 ' this is the speed the vehicle is moving in the VDA direction
VDA = 0 ' VDA is vehicle degree angle = orientation of the vehicle, 0 = pointed right due East
VX = 20 ' this is current x position of vehicle 10 pixles from left side
VY = 20 ' this is current y position of vehicle 10 pixels down from top of screen
DX = SPEED * cos(D2R * VDA) ' this is the horizontal x change on screen due to speed and angle
DY = SPEED * sin(D2R * VDA) ' this is the vertical y change on screen due to speed and angle
'new for HAL the auto pilot, AUTO will also track what stage HAL has advanced to between TIMER calls
AUTO = 0 ' HAL the Auto Pilot sub will be toggled on /off with A or a keypress
TARGET = 0 ' Target x aquired if <> 0
while 1
call gameLoop
wend
end sub
sub gameLoop 'This is the main display of simulation
call pause 100
if BYE then call quit "h"
if VX > .65 * XMAX and AUTO = 1 then call startGame 'not testing this area yet so crashes reported are misleading
if VX > .75 * XMAX then call startGame
if AUTO then
call HAL ' is HAL landing the craft?
else
if VX > .35 then
AUTO = 1
else
if RND(0) < .05 then AUTO = 1 'try to setup sim to run for awhile
end if
end if
'vehicle falls faster and faster, because gravity effects the vertical speed
DY = DY + DG 'speed up falling due to gravity acceleration
'new position = last postion plus the horizontal and vertical changes from momentum
VX = VX + DX
VY = VY + DY
if VX < 20 or VX > XMAX or VY < -100 then
DRIFTS = DRIFTS + 1
'notice "You have drifted off screen."
call startGame
end if
if VY <= LANDY(VX) and FUEL > 0 then
#lander "discard"
#lander "spriteimage lem lem"; int(VDA / 22.5) ' pull up the sprite angled closest to VDA
#lander "spritexy lem "; VX - 15; " "; VY - 24 ' locate on screen
#lander "drawsprites" ' show background and lander
#lander.fuel "cls ;fill red ;place 0 8 ; go ";FUEL ' show fuel usage
if VDA = 90 then
#lander "color yellow"
#lander "place ";VX;" ";VY + 1;"; circlefilled ";2
#lander "place ";VX - 7;" ";VY;"; circlefilled ";1
#lander "place ";VX + 8;" ";VY;"; circlefilled ";1
end if
#lander "color white"
if TARGET then #lander "place ";LZX(TARGET);" ";LZY(TARGET);"; circle ";8
call label 5, 570, "HAL: ";AUTO;" LZ# ";TARGET
call label 130, 570, "VDA: ";VDA
call label 200, 570, "DX: ";int(DX*1000)/1000
call label 300, 570, "DY: ";int(DY)
call label XMAX - 420, 570, "SUCCESS: ";SUCCESS;" TILTS: ";TILTS;" NOT LEVEL: ";LEVEL0;" NO FUEL: ";FUEL0;" OTHER: ";OTHER
else
'attempting to count crashes by type
crash$ = "" : crsh = 0
if VDA <> 90 then crash$ = "Vehicle not upright. " : TILTS = TILTS + 1 : crsh = 1
if DY > 4 then crash$ = crash$ + "Came down too fast. "
if abs(DX) > 4 then crash$ = crash$ + "Still moving hoizontally too fast. "
if FUEL <= 0 then
crash$ = crash$ + "Ran out of fuel. "
if crsh = 0 then FUEL0 = FUEL0 + 1
end if
if LANDY(VX - 7) <> LANDY(VX + 8) then
crash$ = crash$ + "Did not land on level site. "
if crsh = 0 then LEVEL0 = LEVEL0 + 1
end if
if crash$ <> "" then
cause$ = "You crashed!" + chr$(13) + crash$
if crsh = 0 then OTHER = OTHER + 1
'notice cause$
else
call pause 1000 ' to see landings, some look tilted at last moment
SUCCESS = SUCCESS + 1
'notice "Successful landing!"+ chr$(13) + "You lived to land again!"
end if
call startGame
end if
end sub
sub quit H$
timer 0
close #lander
end
end sub
sub control H$, k$
key = asc(right$(k$, 1))
select case key
case 65, 97 : if AUTO then AUTO = 0 else AUTO = 1
case 71, 103 : AUTO = 10 ' God mode
case 81, 113 : BYE = 1
case _VK_UP : call forwardThrust 1
case _VK_LEFT : call rotateLeft
case _VK_RIGHT : call rotateRight
end select
end sub
sub forwardThrust t 'separate from Control so HAL can access thruster
'here is the vertical and horizontal change from a burst of fuel for thrust
thrustx = 2 * t * cos(D2R * VDA + PI)
thrusty = 2 * t * sin(D2R * VDA + PI)
'now change the horizontal and vertical momentums from the thrust
DX = DX + thrustx
DY = DY + thrusty
'update the position
VX = VX + DX
VY = VY + DY
'the thrust cost fuel
FUEL = FUEL - 10 * t
end sub
sub rotateRight 'separate from Control so HAL can access
VDA = VDA + 22.5
if VDA > 337.51 then VDA = 0
FUEL = FUEL - 10
end sub
sub rotateLeft 'separate from Control so HAL can access
VDA = VDA - 22.5
if VDA < -0.01 then VDA = VDA + 360
FUEL = FUEL - 10
end sub
sub HAL 'NEW, HAL is the Happy Auto-pilot Lander program
'HAL is allowed up to 1 command to control module for ajusting the trajectory
'first priority is get upright or nearly so thrusters
if AUTO = 1 then 'look for landing zone coming up
'this case handled first because most of time HAL is called in early
if DX > 0 and VY > 20 then
for i = 1 to LZI
'50 50 at .3,
yDist = .3 * (LZY(i) - VY) 'yDist and yDist - 10 works good but try a little later yet -5 and - 15
if LZX(i) - VX < yDist + 8 and LZX(i) - VX > yDist - 8 then 'straight 123 and 113 OK without yDist
AUTO = 2 : TARGET = i : exit for
end if
next
end if
'handle case DX < 0
'handle case DX = 0
end if
if AUTO = 2 and VY > 30 then
'get DX speed down fast as possible and keep lem up high
if DY > .2 and abs(DX) > 1 then 'thrust up and left or right
if DX < -1 then
'get VDA to 135 before applying forward thrust
if VDA >=0 and VDA < 135 then call rotateRight : exit sub
if VDA >=315 and VDA < 360 then call rotateRight : exit sub
if VDA > 135 and VDA < 315 then call rotateLeft : exit sub
call forwardThrust 1 : exit sub
else
if DX > 1 then
'get VDA to 45 before applying forward thrust
if VDA >= 0 and VDA < 45 then call rotateRight : exit sub
if VDA > 225 and VDA < 360 then call rotateRight : exit sub
if VDA > 45 and VDA <= 225 then call rotateLeft : exit sub
call forwardThrust 1 : exit sub
end if
end if
end if
'drop but not too fast
if DY > 3.5 then
if VDA < 90 then call rotateRight : exit sub
if VDA > 90 then call rotateLeft : exit sub
call forwardThrust 1 : exit sub
end if
'nudge code for drifting wrong way
pdy = (LZY(TARGET) - VY ) / LZY(TARGET)
' condition vehicle X is past target and drifting further past, hey don't nudge if too close vertically
if VX - LZX(TARGET) > 4 * pdy and DX >= 0 and VX - 7 > LZX(TARGET) and LZY(TARGET) - VY > 6 then
AUTO = 3 'for and thrust and then a rotate back
call rotateLeft : exit sub
end if
'condition vehicle x is before target and drifting further to left past
if LZX(TARGET) - VX > 4 * pdy and DX <= 0 and VX + 7 < LZX(TARGET) and LZY(TARGET) - VY > 6 then
AUTO = 5
call rotateRight : exit sub
end if
'another time to nudge
'condition vehicle is upright land < 5 on right or left side and far off on other
if VDA = 90 and LANDY(VX - 7) - VY < 6.5 and LANDY(VX + 8) - VY >= 6.5 then
AUTO = 5
call rotateRight : exit sub
end if
if VDA = 90 and LANDY(VX + 8) - VY < 6.5 and LANDY(VX -7) - VY >= 6.5 then
AUTO = 3
call rotateLeft : exit sub
end if
' before target
if VX < LZX(TARGET) and DX > 0 and DY > 0 then
if LZY(TARGET) - VY > 2 then
if LZY(TARGET) - VY < LZX(TARGET) - VX and abs(LZX(TARGET) - VX) > 2 then
call forwardThrust .4 : exit sub
end if
end if
end if
'nudge
if VX < LZX(TARGET) and DX = 0 and DY > 0 then
if LZY(TARGET) - VY > 2 then
if LZY(TARGET) - VY < LZX(TARGET) - VX and LZX(TARGET) - VX > 2 then
AUTO = 5
call rotateRight : exit sub
end if
end if
end if
' past target
if VX > LZX(TARGET) and DX < -.01 and DY > 0 then
if LZY(TARGET) - VY > 2 then
if LZY(TARGET) - VY < VX - LZX(TARGET) and VX - LZX(TARGET) > 2 then
#lander "color yellow"
#lander "backcolor yellow"
#lander "place ";VX;" ";VY + 1;"; circlefilled ";2
#lander "backcolor black"
call forwardThrust .4 : exit sub
end if
end if
end if
'nudge
if VX > LZX(TARGET) and DX = 0 and DY > 0 then
if LZY(TARGET) - VY > 2 then
if LZY(TARGET) - VY < VX - LZX(TARGET) and VX - LZX(TARGET) > 2 then
if LZY(TARGET) - VY > 3 then
AUTO = 3
call rotateLeft : exit sub
end if
end if
end if
end if
'if VDA < 90 then call rotateRight : exit sub
'if VDA > 90 then call rotateLeft : exit sub
end if 'auto = 2
'after nudge Left
if AUTO = 3 then
AUTO = 4
call forwardThrust .6 : exit sub
end if
if AUTO = 4 then
AUTO = 2 'back to falling after rotation here
if VDA < 90 then call rotateRight : exit sub
end if
'after nudge Right
if AUTO = 5 then
AUTO = 6
call forwardThrust .6 : exit sub
end if
if AUTO = 6 then
AUTO = 2 'back to falling after rotation here
if VDA > 90 then call rotateLeft : exit sub
end if
if AUTO = 10 then 'God mode
VDA = 90 : DX = 0 : FUEL = 500 : DY = 1
ClosestBase = 100000
for i = 1 to LZI
dist = sqr((VX - LZX(i))^2 + (VY - LZY(i))^2)
if dist < ClosestBase then ClosestBase = dist : Base = i
next
VX = LZX(Base) : VY = LZY(Base) - 15 : THANKS = THANKS + 1
AUTO = 1 : LANDINGS = LANDINGS - 1 ' you get no credit for successful landing in God mode
end if
end sub
sub makeSprites
'open "lem" for graphics as #makeSprites
#lander "down"
'#lander "fill black"
#lander "color black"
#lander "place 0 31 ; backColor black ; boxfilled 640 73"
'call pause 2000
for x = 0 to 15
y = 1
call drawLEM x, y, 270 + x * 22.5, 2, "black"
y = 2
call drawLEM x, y, 270 + x * 22.5, 2, "darkgray"
call drawLEM x, y, 270 + x * 22.5, 1, "lightgray"
call getSprite x
'call pause 2000
next x
#lander "addsprite lem lem0 lem1 lem2 lem3 lem4 lem5 lem6 lem7 lem8 lem9 lem10 lem11 lem12 lem13 lem14 lem15"
end sub
sub drawLEM xPosition, yPosition, uncorrectedAngle, penSize, color$
angle = uncorrectedAngle
#lander "north ; color "; color$; " ; up ; turn "; angle
#lander "place "; (xPosition)*30+15; " "; (yPosition-1)*30+15
#lander "size "; penSize
#lander "up ; go 4 ; down ; circlefilled 8"
#lander "turn 75 ; go 4 ; turn 180 ; go 4"
#lander "turn 30 ; go 4 ; turn 180 ; go 4 ; turn 255"
#lander "up ; turn 160 ; go 8"
#lander "down ; go 4 ; turn 110"
#lander "go 8 ; turn 110 ; go 4"
#lander "place "; (xPosition)*30+15; " "; (yPosition-1)*30+15
#lander "north ; up ; turn "; angle
#lander "go 4 ; turn 125 ; go 8 ; down ; turn 45 ; go 8"
#lander "place "; (xPosition)*30+15; " "; (yPosition-1)*30+15
#lander "north ; up ; turn "; angle
#lander "go 4 ; turn 235 ; go 8 ; down ; turn -45 ; go 8"
end sub
sub setBackground
#lander "down ; fill black"
'stars
for s = 1 to 100
c=int(rnd(0)*100+156)
#lander "color ";c;" ";c;" ";c
#lander "size ";int(rnd(0)*4)
#lander "set ";rnd(0)*800;" ";rnd(0)*600
next
call drawTerrain
#lander "getbmp stars 0 0 800 600"
#lander "background stars"
end sub
sub getSprite spritNum
spriteX = spritNum * 30
#lander "getbmp lem"; spritNum; " "; spriteX; " 1 30 60"
end sub
sub drawTerrain
rate1 = rnd(1) / (rnd(1) * 10 + 5)
rate2 = rnd(1) / (rnd(1) * 5 + 5)
#lander "down ; size 1 ; color white"
for x = 0 to XMAX
if rnd(1) < 0.015 and x > 5 then gosub [makeLandingZone]
holder1 = holder1+rate1
holder2 = holder2+rate2
holder3 = holder3+sin(holder2)/20
y = 400+int(sin(holder1)*50)+int(cos(holder2)*50)+int(cos(holder3)*15)
if x <= XMAX then LANDY(x) = y
c=rnd(0)*50+50
#lander "color ";c;" ";c;" ";c;" ; line ";x;" 600 ";x; " ";y
next x
exit sub
[makeLandingZone]
width = int((rnd(1)*4+2)/2) * 32 '32 or 34 original
width = 28 'debug for tighter landing areas to demo pinpoint landings
for lz = x to min(XMAX - 2, x + width)
if lz <= XMAX then LANDY(lz) = y
c=rnd(0)*50+50
#lander "color ";c;" ";c;" ";c;" ; line ";lz;" 600 ";lz; " ";y
next lz
#lander "size 2"
#lander "color darkblue ; line ";x;" ";y;" ";lz;" ";y
#lander "size 1"
if LZI < 15 then 'new, save landing zone data for HAL "to see"
LZI = LZI + 1
LZX(LZI) = x + int(.5 * width) : LZY(LZI) = y
end if
x = lz
return
end sub
sub label x, y, text$
#lander "color white backcolor black"
#lander "place ";x;" ";y
#lander "boxfilled ";x + 7 * len(text$) + 10;" ";y + 20
#lander "place ";x + 5;" ";y + 15;";\";text$
end sub
sub pause ms
timer ms ,[done]
wait
[done]
timer 0
end sub
And if you want to try and land it yourself toggle auto-pilot with key "a" and use left, right and up arrow keys.
If you are sure you are going to crash then hit "g" and pray!