I've made a one liner - called Line
I've made a one liner - called Line
A game about a line, written in a single line of BASIC code
I've been fascinated by Digital Prawn's One Liners since discovering them recently. I was compelled to take up the challenge, and have created my own game, called Line:
I notice that things have been a bit quiet for the last decade on the one liners front - anyone else fancy having a crack at one?
I've been fascinated by Digital Prawn's One Liners since discovering them recently. I was compelled to take up the challenge, and have created my own game, called Line:
I notice that things have been a bit quiet for the last decade on the one liners front - anyone else fancy having a crack at one?
- Alessandro
- Dynamite Dan
- Posts: 1910
- Joined: Wed Nov 15, 2017 11:10 am
- Location: Messina, Italy
- Contact:
Re: I've made a one liner - called Line
Nice! I managed to get to level 10 on my first go.
Out of curiosity, why didn't you make the game run upon loading?
Out of curiosity, why didn't you make the game run upon loading?
Re: I've made a one liner - called Line
A solid first go! I set the max level at 20 mainly because it seems within easy reach enough to hook the player a bit more. However, the escalation in difficulty is quite rapid. The aim is for it to be a digital equivalent to one of those wire loop dexterity tests. Just one more go, I know I can do it this time...
I did just try it on my real Speccy for this first time and unfortunately the blue line is really hard to see compared to on the emulators. Not ideal.
Regarding not saving with LINE 1, I was following what seems to be the convention of those other one liners on Digital Prawn's site. Since you have to keep typing RUN anyway, I figure it at least gives people a chance to see the listing before the colours get changed. That is the focus after all.
I find this format forces clean design. That Connect 4 game on Digital Prawn's sits is so elegant, a real marvel.
There are two features from my original version of this game that I had to drop to fit within the one liner constraints - multiple lives in a game, and better sound effects for dying and game over. Now I'm already wondering if I can get the lives back in. It's quite addictive, optimising over and over.
I did just try it on my real Speccy for this first time and unfortunately the blue line is really hard to see compared to on the emulators. Not ideal.
Regarding not saving with LINE 1, I was following what seems to be the convention of those other one liners on Digital Prawn's site. Since you have to keep typing RUN anyway, I figure it at least gives people a chance to see the listing before the colours get changed. That is the focus after all.
I find this format forces clean design. That Connect 4 game on Digital Prawn's sits is so elegant, a real marvel.
There are two features from my original version of this game that I had to drop to fit within the one liner constraints - multiple lives in a game, and better sound effects for dying and game over. Now I'm already wondering if I can get the lives back in. It's quite addictive, optimising over and over.
Re: I've made a one liner - called Line
It certainly does have that 'just one more go' factor. Surprisingly fun game.
Aye - there is a ZXDB on-liner group, and there's only been 1 of them since Prawn's, Einar's and DrBeep's heyday.
Not me! I'm not averse to certain kinds of coding challenge, but the thought of doing a one-liner gives me the heebeegeebies! Happy to admire what you guys achieve.- anyone else fancy having a crack at one?
Re: I've made a one liner - called Line
I find it horrendous enough not having an 'ELSE' keyword in Sinclair BASIC, never mind having to code an entire game with non-branching logic.
Re: I've made a one liner - called Line
Agreed, having to repeat the condition and resort to GOTOs is so annoying .
There is a secret weapon though once you start peeling apart the examples - POKE 23620,x (the sysvar named NSPPC) which jumps execution to statement x within a line. Since logic operators are evaluated inline you can retain very complex control, for example from Labyrin3D:
Code: Select all
POKE (p+z<i)*23620,8+9*o*(q<i)*(c>1):
Another trick of the trade is using READ and DATA to define and calculate variables instead of LET since they can be combined (e.g. READ a,b,c,d,e,f)
There is one slight edge case to my game. In order to keep the action reasonably fast I DRAW the line in increments of two pixels rather than PLOTing each point. Since the attributes are only checked every two pixels of line it's possible for the line to clip across the corner pixel of an obstacle and turn it blue without a collision. A necessary design compromise though...
- Einar Saukas
- Bugaboo
- Posts: 3147
- Joined: Wed Nov 15, 2017 2:48 pm
Re: I've made a one liner - called Line
Good job!
A few easy tips to make it shorter:
- Initializing variables using READ/DATA doesn't always make it shorter. In your case, eliminate variables 'a' and 'b' (use these values directly in your DRAW statements) to save 4 characters.
- Sometimes simple Math changes can save a lot. For instance, replace this:
with this:Code: Select all
FOR x=10 TO 250 STEP 2: ... INT (x/8)
Code: Select all
FOR x=5 TO 125: ... INT (x/4)
- Don't use parenthesis unless really necessary. For instance, you can save 2 characters replacing this:
with this:Code: Select all
LET k=(4*(INKEY$=" "))-2
although I think it would work better like this:Code: Select all
LET k=4*(INKEY$=" ")-2
This way, users would be able to play the game using whatever key they prefer.Code: Select all
LET k=4*(INKEY$<>"")-2
- Einar Saukas
- Bugaboo
- Posts: 3147
- Joined: Wed Nov 15, 2017 2:48 pm
Re: I've made a one liner - called Line
After eliminating variables 'a' and 'b', you can save another 8 characters replacing this:
with this:
Code: Select all
FOR n=0 TO 1: PLOT 1+n,6+n: DRAW 0,163: DRAW 248,0: DRAW 0,-163: DRAW -248,0: NEXT n: PLOT 250,6
Code: Select all
PLOT 2,170: FOR n=0 TO 1: DRAW 248,0: DRAW 0,n+n-164: DRAW n+n-249,0: DRAW 0,163: NEXT n
- Einar Saukas
- Bugaboo
- Posts: 3147
- Joined: Wed Nov 15, 2017 2:48 pm
Re: I've made a one liner - called Line
Another optimization is to allow Sinclair BASIC to round numbers for you. For instance, instead of this:
use this:
There are several places in your program where you can use this kind of trick.
Code: Select all
INK INT (RND*4)+4
Code: Select all
INT RND*4+3.5
- Einar Saukas
- Bugaboo
- Posts: 3147
- Joined: Wed Nov 15, 2017 2:48 pm
Re: I've made a one liner - called Line
Instead of this:
use this:
Code: Select all
FOR n=9+(l>9) TO 12-(l>9): PRINT AT n,31; INK 0;" ": NEXT n: PRINT AT 0,0; INK 3;"LEVEL ";l
Code: Select all
PRINT INK 3;"LEVEL ";l: FOR n=9+(l>9) TO 12-(l>9): PRINT AT n,31; INK 0;" ": NEXT n
- Einar Saukas
- Bugaboo
- Posts: 3147
- Joined: Wed Nov 15, 2017 2:48 pm
Re: I've made a one liner - called Line
You can remove this statement from the GAME OVER sequence:
At this point, you will already have INK 1 and PAPER 0. The only effect practical effect of this statement is to disable BRIGHT, but it's nearly impossible to distinguish brightness with these colors anyway.
Code: Select all
POKE q,1
- Einar Saukas
- Bugaboo
- Posts: 3147
- Joined: Wed Nov 15, 2017 2:48 pm
Re: I've made a one liner - called Line
To fix this bug, change the start position from (8,85) to (8,84).patters wrote: ↑Tue Jul 30, 2019 12:31 pm There is one slight edge case to my game. In order to keep the action reasonably fast I DRAW the line in increments of two pixels rather than PLOTing each point. Since the attributes are only checked every two pixels of line it's possible for the line to clip across the corner pixel of an obstacle and turn it blue without a collision. A necessary design compromise though...
Re: I've made a one liner - called Line
Great tips, from the master himself
I was just experimenting with the collision detection. The star character is quite small relative to the character block so I was wondering about whether to change it to use POINT rather than ATTR. Drawing each pixel on the line with PLOT is still considerably slower, but if I stick to DRAWing in increments of two I can validate the POINT status at both points for roughly the same overhead as one ATTR lookup. This would allow the line to really skim the obstacles and would make the game feel a lot more fair. Colour clash can be somewhat mitigated by making the entire playfield INK 1 and rendering the line with INK 8. This is less jarring than the line turning obstacles blue. I'll fold in your improvements and post a new version here to see whether people prefer it.
I was just experimenting with the collision detection. The star character is quite small relative to the character block so I was wondering about whether to change it to use POINT rather than ATTR. Drawing each pixel on the line with PLOT is still considerably slower, but if I stick to DRAWing in increments of two I can validate the POINT status at both points for roughly the same overhead as one ATTR lookup. This would allow the line to really skim the obstacles and would make the game feel a lot more fair. Colour clash can be somewhat mitigated by making the entire playfield INK 1 and rendering the line with INK 8. This is less jarring than the line turning obstacles blue. I'll fold in your improvements and post a new version here to see whether people prefer it.
Last edited by patters on Tue Jul 30, 2019 9:06 pm, edited 1 time in total.
Re: I've made a one liner - called Line
How did I not see that.Einar Saukas wrote: ↑Tue Jul 30, 2019 8:17 pm To fix this bug, change the start position from (8,85) to (8,84).
- Einar Saukas
- Bugaboo
- Posts: 3147
- Joined: Wed Nov 15, 2017 2:48 pm
Re: I've made a one liner - called Line
Thanks!
I think it would look good to use the hash sign '#', but setting a different PAPER instead of INK.
- Einar Saukas
- Bugaboo
- Posts: 3147
- Joined: Wed Nov 15, 2017 2:48 pm
Re: I've made a one liner - called Line
Another idea is to use either hash sign '#' or capital 'O', setting PAPER 1 and a different INK. It will give the impression there's a faint force field around each obstacle. This way, these obstacles won't look as blocky, but the collision will always seem correct.Einar Saukas wrote: ↑Tue Jul 30, 2019 10:04 pm I think it would look good to use the hash sign '#', but setting a different PAPER instead of INK.
Yet another option is using the copyright symbol that fills almost the entire character block, but I don't think it will look as good.
Re: I've made a one liner - called Line
Hmm. I've really convinced myself that ATTR collision detection is not a good fit here, so I've switched to POINT. The main issue is that as the later levels get congested with obstacles, the player needs to be able to cut a diagonal between closely packed obstacles. If you can't do this then it seems too unfair. This is a remake of a game I had played at school, and on that computer I'm pretty sure collisions were pixel accurate, so this feels more faithful.
Download link
The game is a bit faster now which I think makes it more addictive, but it's a lot more achievable though still challenging. In fact I just completed it for the first time. I've improved the sound a bit, and added a completion screen. The collision detection is only checked every two pixels on the line, but I think with the current grid alignment it's working well. What do you think Einar?
Code: Select all
FOR l=1 TO 20:
POKE 23693,65:
BORDER 0:
CLS :
INK 2:
PLOT 2,170:
FOR n=0 TO 1:
DRAW 247,0:
DRAW 0,n+n-164:
DRAW n+n-248,0:
DRAW 0,163:
NEXT n:
PRINT INK 3;"LEVEL ";l:
FOR n=9+(l>9) TO 12-(l>9):
PRINT AT n,31; INK 1;" ":
NEXT n:
INK RND*4+3.5:
FOR n=0 TO l*3+20:
PRINT AT RND*18+1.5,RND*26+3.5;"*":
BEEP .0001,60:
NEXT n:
INK 8:
LET y=85:
PLOT 8,y:
FOR x=5 TO 125:
LET k=4*(INKEY$<>"")-2:
LET y=y+k: POKE 23620*POINT (2*x,y),34:
DRAW 2,k:
NEXT x:
BEEP .01,20:
BEEP .01,30:
NEXT l:
DIM a$(32):
BRIGHT 0:
INK 1+5*(l=21):
FOR n=0 TO 6:
BEEP .005,20-5*n:
NEXT n:
FOR n=0 TO 10:
PRINT AT n,0; OVER 1;a$;AT 21-n,0;a$:
NEXT n:
PRINT AT 10,n; INK 7;"GAME OVER" AND l<21;"WELL DONE" AND l=21
The game is a bit faster now which I think makes it more addictive, but it's a lot more achievable though still challenging. In fact I just completed it for the first time. I've improved the sound a bit, and added a completion screen. The collision detection is only checked every two pixels on the line, but I think with the current grid alignment it's working well. What do you think Einar?
Re: I've made a one liner - called Line
Here is a version which sacrifices the better sounds in order to offer the player three lives with a visual indicator in the bottom right of the screen. Given that the game runs faster, I think this is a good addition. In order to get it under the one screen limit I have had to re-use the 'e' variable a few times.
Download link
Any further optimisations here that might allow the sounds as well, particularly the obstacle placement beep?
Code: Select all
READ p,q,e,l,d$:
FOR d=0 TO 2:
POKE q,65:
BORDER 0:
CLS :
INK 2:
PLOT 2,170:
FOR n=0 TO 1:
DRAW 247,0:
DRAW 0,n+n-164:
DRAW n+n-248,0:
DRAW 0,163:
NEXT n:
PRINT INK 3;"LEVEL ";l:
FOR n=9+(l>9) TO 12-(l>9):
PRINT AT n,31; INK 1;" ";AT 20,29+d;d$( TO 2-d):
NEXT n:
INK RND*4+3.5:
FOR n=0 TO l*3+e:
PRINT AT RND*18+1.5,RND*26+3.5;"*":
NEXT n:
INK 8:
LET y=85:
PLOT 8,y:
FOR x=5 TO 125:
LET k=4*(INKEY$<>"")-2:
LET y=y+k:
POKE p*POINT (2*x,y),34:
DRAW 2,k:
NEXT x:
LET l=l+1:
BEEP .02,30:
POKE p,3+33*(l=e):
BEEP .2,-e:
NEXT d:
DIM a$(32):
INK 1+5*(l=e):
FOR n=0 TO 10:
PRINT AT n,0; OVER 1;a$;AT 21-n,0;a$:
NEXT n:
PRINT AT 10,n; INK 7;"GAME OVER" AND l<e;"WELL DONE" AND l=e:
DATA 23620,p+73,21,1,"//"
Any further optimisations here that might allow the sounds as well, particularly the obstacle placement beep?
Last edited by patters on Wed Jul 31, 2019 2:03 pm, edited 4 times in total.
Re: I've made a one liner - called Line
If it's only checking every 2 pixels, surely you need obstacles that have two-pixel thick lines so you don't skip straight through one?
Re: I've made a one liner - called Line
I have play tested it a lot and I think it's fine. The border lines are two pixels thick, and the stars don't really have corners to skip though if you're on a diagonal trajectory. Basically if you're going to clip the star at all you'll hit it with the subsequent pixel - mainly because of the current grid alignment (which can only change by 2 units at a time). Give it a try. I just updated the latest version btw. Had some issues with it which are now resolved, but it's been tricky to get it back under the one screen limit.
Re: I've made a one liner - called Line
Updated again to combine the creation of the gate into the red playfield outline loop. Is there a tighter way to encode these DRAW operations I wonder...
Code: Select all
READ p,q,e,l,d$:
FOR d=0 TO 2:
POKE q,65:
BORDER 0:
CLS :
INK 2:
LET g=8*(l>9)
PLOT 2,170:
FOR n=0 TO 1:
DRAW 247,0:
DRAW 0,n-66-g:
PLOT 249-n,71+g:
DRAW 0,n-65-g:
DRAW n+n-248,0:
DRAW 0,163:
NEXT n:
PRINT INK 3;"LEVEL ";l;AT 20,29+d; INK 1;d$( TO 2-d):
INK RND*4+3.5:
FOR n=0 TO l*3+e:
PRINT AT RND*18+1.5,RND*26+3.5;"*":
NEXT n:
INK 8:
LET y=85:
PLOT 8,y:
FOR x=5 TO 125:
LET k=4*(INKEY$<>"")-2:
LET y=y+k:
POKE p*POINT (2*x,y),34:
DRAW 2,k:
NEXT x:
LET l=l+1:
BEEP .02,30:
POKE p,3+33*(l=e):
BEEP .2,-e:
NEXT d:
DIM a$(32):
INK 1+5*(l=e):
FOR n=0 TO 10:
PRINT AT n,0; OVER 1;a$;AT e-n,0;a$:
NEXT n:
PRINT AT 10,n; INK 7;"GAME OVER" AND l<e;"WELL DONE" AND l=e:
DATA 23620,p+73,21,1,"//"
- Einar Saukas
- Bugaboo
- Posts: 3147
- Joined: Wed Nov 15, 2017 2:48 pm
Re: I've made a one liner - called Line
Instead of this:
Use this:
However the lives indicator looks much better using INK 3. In this case, the code will be much shorter:
Code: Select all
FOR d=0 TO 2: ... PRINT INK 3;"LEVEL ";l;AT 20,29+d; INK 1;d$( TO 2-d)
Code: Select all
FOR d=1 TO 3: ... PRINT INK 3;"LEVEL ";l;AT 20,28+d; INK 1;d$(d TO )
Code: Select all
FOR d=1 TO 3: ... PRINT INK 3;"LEVEL ";l;AT 20,28+d;d$(d TO )
- Einar Saukas
- Bugaboo
- Posts: 3147
- Joined: Wed Nov 15, 2017 2:48 pm
- Einar Saukas
- Bugaboo
- Posts: 3147
- Joined: Wed Nov 15, 2017 2:48 pm
Re: I've made a one liner - called Line
You can also consider replacing this:
with this:
It won't work exactly the same way, since the incidence of stars in the first and last rows, also first and last columns, will be reduced by 50%. But I think it looks even better this way. It looks good to have a higher concentration of stars closer to the center of the galaxy, not as many stars near the edge...
Alternatively you could expand the stars area sideways, to make the game a little more challenging, as follows:
Code: Select all
PRINT AT RND*18+1.5,RND*26+3.5;"*"
Code: Select all
PRINT AT RND*17+2,RND*25+4;"*"
Alternatively you could expand the stars area sideways, to make the game a little more challenging, as follows:
Code: Select all
PRINT AT RND*17+2,RND*27+3;"*"
- Einar Saukas
- Bugaboo
- Posts: 3147
- Joined: Wed Nov 15, 2017 2:48 pm
Re: I've made a one liner - called Line
I suggest replacing this:
with this:
It's the same size, but runs a little bit faster.
Code: Select all
POKE p*POINT (2*x,y),34
Code: Select all
POKE p*POINT (x+x,y),34