SAY WHAT????
Yeah, I know. I'm not sure from where I got the idea but I found the
source code to a Lunar Lander game in the book '101 BASIC Computer
Games' by David Ahl at (the now defunct) Creative Computers magazine.
Having copious spare time on my hands, because I'm currently
unemployed, I converted the old BASIC program to C for the Arduino.
Now I remember why I don't do BASIC anymore... even on a Parallax
chip. :o
It's not the greatest C code but that BASIC stuff didn't have a lick of
comments so I just tried to get it to run pretty much like the sample
output despite the sauce on all that spaghetti. It's purely text w/ no
graphics of any kind, even ASCII, and it's a bit finicky about your burn
rate input . Still, it does appear to work on a '328 and is small enough
that it should work on a '168 as well. Wanna make it work on a Tiny85?
Knock yerself out!!!
A scanned page from the book is here:
and much clearer source code is here:
http://www.vintage-basic.net/bcg/lunar.bas
My code follows. Give it a try for some retro-'puting.
How deep is YOUR crater??? Enjoy!
-Rusty-
void setup()
{
Serial.begin(115200);
delay(1000);
Serial.println("\t\t\t\t LUNAR");
Serial.println("\t CREATIVE COMPUTING MORRISTOWN, NEW JERSEY");
Serial.println("\n\n");
Serial.println("THIS IS A COMPUTER SIMULATION OF AN APOLLO LUNAR");
Serial.println("LANDING CAPSULE.\n\n");
Serial.println("THE ON-BOARD COMPUTER HAS FAILED (IT WAS MADE BY");
Serial.println("XEROX) SO YOU HAVE TO LAND THE CAPSULE MANUALLY.");
}
float L, A, V, M, N, G, Z, K, T, S, W, I, J;
float input(char *p)
{
int ans;
byte n;
restart:
ans = 0;
if (p == NULL)
Serial.print("? ");
else
Serial.print(p);
for (;;) {
if (Serial.available()) {
n = Serial.read();
Serial.print(n, BYTE);
if ((n == '\r') || (n == '\n')) {
Serial.println();
break;
}
else if (n == '\010') { // backspace
Serial.print(" \010");
ans /= 10;
}
else if (isdigit(n)) {
ans = ans*10 + (n - '0');
}
else {
Serial.println("\n\rERROR: BAD INPUT. TRY AGAIN");
goto restart;
}
}
}
return (float)ans;
}
void landing()
{
W = 3600.0 * V;
Serial.print("ON MOON AT ");
Serial.print(L);
Serial.print(" SECONDS - IMPACT VELOCITY ");
Serial.print(W);
Serial.println(" MPH");
if (W <= 1.2)
Serial.println("PERFECT LANDING!");
else if (W <= 10.0)
Serial.println("GOOD LANDING (COULD BE BETTER)");
else if (W <= 60.0) {
Serial.println("CRAFT DAMAGE... YOU'RE STRANDED HERE UNTIL A RESCUE");
Serial.println("PARTY ARRIVES. HOPE YOU HAVE ENOUGH OXYGEN!");
} else {
Serial.println("SORRY THERE WERE NO SURVIVORS. YOU BLEW IT!");
Serial.print("IN FACT, YOU BLASTED A NEW LUNAR CRATER ");
Serial.print(W*0.277);
Serial.println(" FEET DEEP!");
}
Serial.println("\n\n\nTRY AGAIN?");
}
void sub420()
{
float q, q2, q3, q4, q5;
q = S * K/M;
q2 = q * q;
q3 = q * q2;
q4 = q * q3;
q5 = q * q4;
J=V+G*S+Z*(-q - (q2/2.0) - (q3/3.0) - (q4/4.0) - (q5/5.0));
I=A-G*S*S/2.0-V*S+Z*S*(q/2.0 + q2/6.0 + q3/12.0 + q4/20.0 + q5/30.0);
}
void sub330()
{
L += S;
T -= S;
M -= S*K;
A = I;
V = J;
}
void sub340() {
float D;
for ( ;S >= 5.0e-3; ) { // line 340
D = V + sqrt(V*V+2.0*A*(G-Z*K/M));
S = 2.0 * A / D;
sub420();
sub330();
}
}
void loop()
{
char line[80];
Serial.println("\nSET BURN RATE OF RETRO ROCKETS TO ANY VALUE BETWEEN");
Serial.println("0 (FREE FALL) AND 200 (MAXIMUM BURN) POUNDS PER SECOND.");
Serial.println("SET NEW BURN RATE EVERY 10 SECONDS.\n");
Serial.println("CAPSULE WEIGHT 32,500 LBS; FUEL WEIGHT 16,500 LBS.");
Serial.println("\n\n\nGOOD LUCK");
L=0;
Serial.println("\nSEC\tMI + FT \tMPH\tLB FUEL\t\tBURN RATE\n");
A=120.0; V=1.0; M=33000.0; N=16500.0; G=1.0e-3; Z=1.8;
for (;;) { // line 150
sprintf(line, " %-d\t %d %-4d\t %d\t %d\t\t",
(int)L, (int)floor(A),
(int)floor(5280.0*(A-floor(A))),
(int)(3600.0*V), (int)(M-N));
Serial.print(line);
K = input(NULL);
T = 10.0;
for (;;) { // line 160
if ((M-N) < 1.0e-3) {
Serial.print("FUEL OUT AT ");
Serial.print(L);
Serial.println(" SECONDS");
S = (-V + sqrt(V*V + 2*A*G))/G;
V += G*S;
L += S;
landing();
return; // Game over, Man!
}
if (T < 1.0e-3) // line 170
break;
S = T;
if (M < (N+S*K))
S = (M-N)/K;
sub420();
if (I <= 0.0) {
sub340();
landing();
return;
}
if ((V <= 0.0) || (J >= 0.0)) {
sub330();
continue; // back to line 160
}
// line 370
do {
W = (1.0 - M*G/(Z*K))/2.0;
S = M*V/(Z*K*(W+sqrt(W*W+V/Z))) + 0.05;
sub420();
if (I <= 0.0) {
sub340();
landing();
return;
}
sub330();
if (J > 0.0)
break;
} while (V > 0.0);
}
}
}