|
Post by David Drake on Jan 31, 2020 12:37:21 GMT -5
Rod and tsh73, you are really stretching the language to its limits. My hat is off to you, clever gurus. I'd love to learn more about associative arrays. This is just minimal contribution, but you can do some combining on lines 3, 4, 5 and 6 and save a few characters: Next: Lunar lander in 1K? ;-) How about this for a "lander" in 1200 characters? Not as full featured as the example included with LB, but it works. Use the [ and ] to steer and + to fire the vertical thrusters. Yes, you're flying a box. But still... nomainwin
prompt "Difficulty (1-4)?";f
UpperLeftX = 1
UpperLeftY = 1
WindowWidth=800
WindowHeight=600
open "" for graphics_nsb_nf as #1
#1 "trapclose [q];when characterInput [k];fill black;setfocus;color white;size 2;down;getbmp b 1 1 800 600;color white;size 2;down;place 1 21;boxfilled 21 41;getbmp j 1 1 20 40"
#1 "fill black;place 1 11;turn 180;size 5;go 10;getbmp m 1 1 5 20;fill black;place 1 11;turn 180;color red;size 5;go 10;getbmp n 1 1 5 20;addsprite L j;background b"
landx=int(rnd(1)*650)
x=10
y=10
dx=f
dy=f
s=350
for a=1 to 800 step 4
c=3*f*(2-int(rnd(1)*5))
if a>landx+int(100/f) or a<landx then
s=s+c
if s<200 then s=200
if s>550 then s=550
#1 "addsprite M";a;" m;spritexy M";a;" ";a;" ";s
else
#1 "addsprite N";a;" n;spritexy N";a;" ";a;" ";s
end if
next a
timer 1000,[a]
wait
[a]
dy=dy+1
x=x+dx
y=y+dy
if x>800-20 or x<1 then [b]
if y>600-20 or y<1 then [b]
#1 "spritexy L ";x;" ";y;";drawsprites;spritecollides L d$"
if instr(d$,"M")>0 then [b]
if instr(d$,"N")>0 then [c]
wait
[k]
a$=Inkey$
if a$="=" then dy=dy-5
if a$="[" then dx=dx-1
if a$="]" then dx=dx+1
wait
[b] notice "Dead":goto [q]
[c] if dy>4 or dx>2 or dx<-2 then notice "Crash" else notice "Landed!"
[q] close #1:end
|
|
|
Post by Carl Gundel on Jan 31, 2020 15:24:51 GMT -5
Next: Lunar lander in 1K? ;-) How about this for a "lander" in 1200 characters? Not as full featured as the example included with LB, but it works. Use the [ and ] to steer and + to fire the vertical thrusters. Yes, you're flying a box. But still... nomainwin
prompt "Difficulty (1-4)?";f
UpperLeftX = 1
UpperLeftY = 1
WindowWidth=800
WindowHeight=600
open "" for graphics_nsb_nf as #1
#1 "trapclose [q];when characterInput [k];fill black;setfocus;color white;size 2;down;getbmp b 1 1 800 600;color white;size 2;down;place 1 21;boxfilled 21 41;getbmp j 1 1 20 40"
#1 "fill black;place 1 11;turn 180;size 5;go 10;getbmp m 1 1 5 20;fill black;place 1 11;turn 180;color red;size 5;go 10;getbmp n 1 1 5 20;addsprite L j;background b"
landx=int(rnd(1)*650)
x=10
y=10
dx=f
dy=f
s=350
for a=1 to 800 step 4
c=3*f*(2-int(rnd(1)*5))
if a>landx+int(100/f) or a<landx then
s=s+c
if s<200 then s=200
if s>550 then s=550
#1 "addsprite M";a;" m;spritexy M";a;" ";a;" ";s
else
#1 "addsprite N";a;" n;spritexy N";a;" ";a;" ";s
end if
next a
timer 1000,[a]
wait
[a]
dy=dy+1
x=x+dx
y=y+dy
if x>800-20 or x<1 then [b]
if y>600-20 or y<1 then [b]
#1 "spritexy L ";x;" ";y;";drawsprites;spritecollides L d$"
if instr(d$,"M")>0 then [b]
if instr(d$,"N")>0 then [c]
wait
[k]
a$=Inkey$
if a$="=" then dy=dy-5
if a$="[" then dx=dx-1
if a$="]" then dx=dx+1
wait
[b] notice "Dead":goto [q]
[c] if dy>4 or dx>2 or dx<-2 then notice "Crash" else notice "Landed!"
[q] close #1:end
Wow you didn't waste any time? :-D I can't wait to try this. Can we make a new thread for it?
|
|
|
Post by tsh73 on Jan 31, 2020 16:15:53 GMT -5
Here are you are
|
|
|
Post by Carl Gundel on Jan 31, 2020 16:43:30 GMT -5
Here are you are Thank you!
|
|
|
Post by Carl Gundel on Jan 31, 2020 19:06:35 GMT -5
Next: Lunar lander in 1K? ;-) How about this for a "lander" in 1200 characters? Not as full featured as the example included with LB, but it works. Use the [ and ] to steer and + to fire the vertical thrusters. Yes, you're flying a box. But still... <code snipped>
Nice job. A good minimal lander game.
|
|
|
Post by Brandon Parker on Feb 10, 2020 11:59:44 GMT -5
Prior to your Prompt statement, you should set the "f" variable equal to 1 that way it will show up in the Prompt set to 1 instead of 0. I think you should also ensure the value is between 1 and 4 if that is what you are expecting the user to enter.
f = 1 prompt "Difficulty (1-4)?";f f = Min(Max(1, f), 4)
This will add more to the code size but it will prevent a division by zero error as well as limit the difficulty to the specified range.
{:0)
Brandon Parker
|
|
|
Post by Brandon Parker on Feb 10, 2020 12:16:49 GMT -5
One optimization would be to remove the If..Then control construct and simply use math to cause the control of the lander to change.
Instead of this code ...
if a$="=" then dy=dy-5 if a$="[" then dx=dx-1 if a$="]" then dx=dx+1
You could use this code ...
dy=((a$="=")*(-5))+dy dx=((a$="[")*(-1))+(a$="]")+dx
{:0)
Brandon Parker
|
|
|
Post by Brandon Parker on Feb 10, 2020 13:24:08 GMT -5
Here is another size-reduction that is pretty straight forward. All of these types of If...Then statements can normally be simplified (... depending on how you look at it ...)
Instead of this code ...
if s<200 then s=200 if s>550 then s=550
You coudl use this code ...
s=Min(Max(200, s), 550)
{:0)
Brandon Parker
|
|
|
Post by Brandon Parker on Feb 10, 2020 13:48:45 GMT -5
Removing the ">0" from the two lines below saves some size as well. Since the If...Then is Boolean check and Instr() returns >=1 if the substring exists there is no need for checking for >0. It looks like that saves an additional 8 Bytes or so.
Instead of this ...
if instr(d$,"M")>0 then [b] if instr(d$,"N")>0 then [c]
Use this ...
if instr(d$,"M") then [b] if instr(d$,"N") then [c]
{:0)
Brandon Parker
|
|
|
Post by Brandon Parker on Feb 10, 2020 13:55:55 GMT -5
Ohhhh....this is fun ...
Yet another size optimization would be to change the following lines and then just combine them. Since you are checking against hard-coded boundaries we can remove the "-20" from each line and then combine them.
Instead of this ...
if x>800-20 or x<1 then [b] if y>600-20 or y<1 then [b]
Use this ...
if x>780 or x<1 or y>580 or y<1 then [b]
This reduces the size by about 23 Bytes!
You can also remove the "a$" variable and just use Inkey$ since you are not modifying it. This saves another 11 Bytes and brings it down to 1836 Bytes on my machine when tokenized.
[k] dy=((Inkey$="=")*(-5))+dy dx=((Inkey$="[")*(-1))+(Inkey$="]")+dx
Here is what I have done to it so far ...
nomainwin
f = 1 prompt "Difficulty (1-4)?";f f = Min(Max(1, f), 4)
UpperLeftX = 1
UpperLeftY = 1
WindowWidth=800
WindowHeight=600
open "" for graphics_nsb_nf as #1
#1 "trapclose [q];when characterInput [k];fill black;setfocus;color white;size 2;down;getbmp b 1 1 800 600;color white;size 2;down;place 1 21;boxfilled 21 41;getbmp j 1 1 20 40"
#1 "fill black;place 1 11;turn 180;size 5;go 10;getbmp m 1 1 5 20;fill black;place 1 11;turn 180;color red;size 5;go 10;getbmp n 1 1 5 20;addsprite L j;background b"
landx=int(rnd(1)*650)
x=10
y=10
dx=f
dy=f
s=350
for a=1 to 800 step 4
c=3*f*(2-int(rnd(1)*5))
if a>landx+int(100/f) or a<landx then
s=s+c
s=Min(Max(200, s), 550)
#1 "addsprite M";a;" m;spritexy M";a;" ";a;" ";s
else
#1 "addsprite N";a;" n;spritexy N";a;" ";a;" ";s
end if
next a
timer 1000,[a]
wait
[a]
dy=dy+1
x=x+dx
y=y+dy
if x>780 or x<1 or y>580 or y<1 then [b]
#1 "spritexy L ";x;" ";y;";drawsprites;spritecollides L d$"
if instr(d$,"M") then [b]
if instr(d$,"N") then [c]
wait
[k] dy=((Inkey$="=")*(-5))+dy dx=((Inkey$="[")*(-1))+(Inkey$="]")+dx
wait
[b] notice "Dead":goto [q]
[c] if dy>4 or dx>2 or dx<-2 then notice "Crash" else notice "Landed!"
[q] close #1:end
{:0)
Brandon Parker
|
|
|
Post by David Drake on Feb 11, 2020 8:02:58 GMT -5
This reduces the size by about 23 Bytes! Brandon, I'm glad you are having fun with this. Great ideas! I'm learning more and more coding tricks with these "small code" challenges. Another idea, if you really want to get crazy and you don't care about aesthetics, you can use the shortest color names (instead of black and white use blue and red), and take out a couple of redundant "down" and "size" commands, and some of the code becomes #1 "trapclose [q];when characterInput [k];fill blue;setfocus;color red;size 2;down;getbmp b 1 1 800 600;place 1 21;box 21 41;getbmp j 1 1 20 40" #1 "fill blue;place 1 11;turn 180;size 5;go 10;getbmp m 1 1 5 20;fill blue;place 1 11;turn 180;go 10;getbmp n 1 1 5 20;addsprite L j;background b"
I also removed some unneeded spaces and carriage returns, set the timer to 500ms (which improves game play and saves a character), and deleted the "nomainwin," "UpperLeftX" and "UpperLeftY" statements. This knocks off a few more characters but makes the program a little less polished. Current count, I believe, is 1,079 characters, for the code below: f=1 prompt "Difficulty (1-4)?";f f=Min(Max(1,f),4) WindowWidth=800 WindowHeight=600 open "" for graphics_nsb_nf as #1 #1 "trapclose [q];when characterInput [k];fill blue;setfocus;color red;size 2;down;getbmp b 1 1 800 600;place 1 21;box 21 41;getbmp j 1 1 20 40" #1 "fill blue;place 1 11;turn 180;size 5;go 10;getbmp m 1 1 5 20;fill blue;place 1 11;turn 180;go 10;getbmp n 1 1 5 20;addsprite L j;background b" landx=int(rnd(1)*650) x=10 y=10 dx=f dy=f s=350 for a=1 to 800 step 4 c=3*f*(2-int(rnd(1)*5)) if a>landx+int(100/f) or a<landx then s=s+c s=Min(Max(200,s),550) #1 "addsprite M";a;" m;spritexy M";a;" ";a;" ";s else #1 "addsprite N";a;" n;spritexy N";a;" ";a;" ";s end if next a timer 500,[a] wait [a] dy=dy+1 x=x+dx y=y+dy if x>780 or x<1 or y>580 or y<1 then [b] #1 "spritexy L ";x;" ";y;";drawsprites;spritecollides L d$" if instr(d$,"M") then [b] if instr(d$,"N") then [c] wait [k] dy=((Inkey$="=")*(-5))+dy dx=((Inkey$="[")*(-1))+(Inkey$="]")+dx wait [b] notice "Dead":goto [q] [c] if dy>4 or dx>2 or dx<-2 then notice "Crash" else notice "Landed!" [q] close #1:end
David
|
|
|
Post by tsh73 on Feb 11, 2020 8:35:05 GMT -5
How do you count it? I paste it to Notepad++ and it says
I save it and Windows says
EDIT btw joining lines saves one character - ":" instead of "CR LF"
|
|
|
Post by Brandon Parker on Feb 11, 2020 9:18:16 GMT -5
I would go off of compiled Byte count personally. I would leave it a little more polished in some places as well specifically with the NoMainWin command.
We can lose one Byte by changing the following:
Instead of this ...
x=10
y=10
Use this ...
x=10
y=x
Since they are initialized to the same thing, the reduction from setting y equal to "10" to y equal to "x" lowers the compiled Byte count by one.
{:0)
Brandon Parker
|
|
|
Post by Rod on Feb 11, 2020 9:58:04 GMT -5
Well 991 just counting the .bas file characters. I had to fudge the graphics but it still plays! I also dropped the int() functions as the sprite engine is quite happy with floats. And a few other tweaks. Just enough space to add back nomainwin!
r$="Dead":f=1:prompt "Level (1-4)?";f f=min(4,f):WindowWidth=800:WindowHeight=600 open "" for graphics_nsb_nf as #1 #1 "trapclose [b];when characterInput [k];fill blue;setfocus;down;size 4;fill blue;color red;getbmp b 0 0 800 600;place 0 20;box 20 40;getbmp j 0 0 20 40;getbmp m 17 10 17 20;getbmp n 0 10 10 20;addsprite L j;background b" lx=rnd(1)*650:x=10:y=10:dx=f:dy=f:s=350 for a=1 to 800 step 4 c=3*f*(2-rnd(1)*5) if a>lx+100/f or a<lx then s=s+c:s=Min(Max(200,s),550):#1 "addsprite M";a;" m;spritexy M";a;" ";a;" ";s else #1 "addsprite N";a;" n;spritexy N";a;" ";a;" ";s end if next a timer 500,[a] wait [a] dy=dy+1:x=x+dx:y=y+dy if x>780 or x<1 or y>580 or y<1 then [b] #1 "spritexy L ";x;" ";y;";drawsprites;spritecollides L d$" if instr(d$,"M") then [b] if instr(d$,"N") then if dy>4 or dx>2 or dx<-2 then r$="Crash" else r$="Landed":goto [b] end if:wait [k] k$=Inkey$:dy=((k$="=")*(-5))+dy:dx=((k$="[")*(-1))+(k$="]")+dx wait [b] notice r$:close #1:end
|
|
|
Post by Rod on Feb 11, 2020 10:02:38 GMT -5
I notice that compiling to .tkn adds to the byte count! .bas is 991 but .tkn comes out at 1594 I vote for .bas
|
|