Log In  

This is a very simple snake clone, left to turn left, right to turn right, collect the apples. If you hit your tail the game crashes (on purpose) and the score is shown.

I really wanna get it under 280 characters but I'm not sure I can really get it any further, so if you're up for it, I'd love to hear from you about how I can go further :)

265 chars (with a lot of help from remcode and jadelombax!)

d={}u,w,x,y=0,0,4,4
d={}u=0w=0y=4x=4
cls()::_::b=btn()w+=(b%2-b%4\2)/50
x+=1.5*cos(w)y+=sin(w)*1.5if(2<pget(x,y)or u<1)u+=1circ(l,m,2,0)l=rnd(99)m=rnd(99)
if(pget(x,y)>1)print(u)()
add(d,{x,y,2,u})for e in all(d)do e[4]-=.1pset(unpack(e))
if(e[4]<0)e[3]=1
end
circ(l,m,2,3)flip()goto _

Property descriptions

d = tail table
u = score
w = snake direction
x = snake x pos
y = snake y pos

l = apple x
m = apple y
P#79248 2020-07-13 12:52 ( Edited 2020-07-13 18:30)

2

For one line if statements, pico-8 allows a shorter method, by putting the condition in brackets, then and end can be omitted, such that:

if b(x,y)>5 then print(u)_()end

could be:

if (b(x,y)>5) print(u)_()

and there are a few other if statements on one line that could also use this.


(Deleted another comment because it was no longer a saving. =/ )

P#79249 2020-07-13 13:03 ( Edited 2020-07-13 13:17)

oh awesome, I was not aware of that, I'll update!

P#79250 2020-07-13 13:05

If you can use v, z, and n directly, rather than as variables, you can save a few characters (because the commas increase the amount of characters it takes to use them as variables). I think all 3 of them would benefit from this, but check it (and if you did want them to change, this wouldn't be suitable).

And .02 can be used instead of 0.02

P#79253 2020-07-13 13:34 ( Edited 2020-07-13 13:41)

you're right that's another saving, down to 314 now

P#79254 2020-07-13 13:42 ( Edited 2020-07-13 13:45)

I think you can use: if(e[3]<0)c(e[1],e[2],0)e=nil

P#79255 2020-07-13 13:52 ( Edited 2020-07-13 13:52)

By not using b=pget, but using pget directly you can save a single character. =/

P#79256 2020-07-13 13:55

I did try that actually, but it seemed to mess about with the way the drawing works, it seems to be drawing over some of the tail parts early.

I wondered if nilling confused the for loop in a way a del call doesn't?

P#79257 2020-07-13 13:59

And another single character with the first line as: d={}a,c,u,w,x,y,l,m=circ,pset,0,0,9,9,9,9

Beyond that, I think you're looking at rejigging how your code works. =/ I'm going to have to leave that to you.

P#79258 2020-07-13 13:59

Thank you for your efforts remcode :)

P#79259 2020-07-13 14:02

Re: I did try that

Shame that doesn't work; I wasn't sure with that one. Yes, you're probably right about it confusing the for loop. del will remove the element and shift the later items down, which is a nice clean way of doing it.

P#79260 2020-07-13 14:04

A few more small savings:

  • I think circ doesn't have to be a variable
  • l,m=rnd(99),rnd(99) can be l=rnd(99)m=rnd(99)
  • I said one line if, but it doesn't have to start at the start of the line (just, it goes to the end of the line, so use cautiously)
d={}u,w,x,y=0,0,4,4
cls()::_::
if(btn(0))w+=.02
if(btn(1))w-=.02
x+=cos(w)*1.5
y+=sin(w)*1.5if(2<pget(x,y)or u<1)u+=1circ(l,m,2,0)l=rnd(99)m=rnd(99)circ(l,m,2,3)
if(pget(x,y)>1)print(u)()
for e in all(d)do e[3]-=.1if(e[3]<0)pset(e[1],e[2],1)del(d,e)
end
pset(x,y,2)add(d,{x,y,u})flip()goto _
P#79261 2020-07-13 14:36 ( Edited 2020-07-13 14:39)

Thanks rem, almost into the 280's!

P#79262 2020-07-13 14:44

A long ugly line (taking advantage of the ) after cos(w) to save another character: x+=1.5*cos(w)y+=sin(w)*1.5if(2<pget(x,y)or u<1)u+=1circ(l,m,2,0)l=rnd(99)m=rnd(99)circ(l,m,2,3)

P#79263 2020-07-13 14:50
1

Got it! 278

d={}u,w,x,y=0,0,4,4
cls()::_::
if(btn(0))w+=.02
if(btn(1))w-=.02
x+=1.5*cos(w)y+=sin(w)*1.5if(2<pget(x,y)or u<1)u+=1circ(l,m,2,0)l=rnd(99)m=rnd(99)
if(pget(x,y)>1)print(u)()
add(d,{x,y,2,u})for e in all(d)do e[4]-=.1pset(unpack(e))
if(e[4]<0)e[3]=1
end
circ(l,m,2,3)flip()goto _

Incorporated the pset of the head at x and y into the array, dropped the del, a little rearranging, use of unpack while counting on a fourth argument to be ignored.


I'm not sure how robust it is with the omitted del and some of the other changes. =/ But it is sub 280.

P#79265 2020-07-13 15:35 ( Edited 2020-07-13 19:21)

How very cool, thank you for your input. I was at about 450 characters yesterday and couldn't imagine getting close.

P#79266 2020-07-13 15:43 ( Edited 2020-07-13 15:48)

Thanks for the challenge; it was fun to work on. :)

P#79267 2020-07-13 15:48
2

Cool, that's a neat take on snake, I haven't seen one that actually, well, moves like a snake =).
If you're interested, there's a couple things you can do to cut out a few more characters.
The first is that while declaring variables with commas and a single equals sign saves tokens, it can actually use a few more characters. There's also room to cut down the L/R controls a bit more:

d={}x=0y=0u=0w=0
cls()::_::b=btn()w+=(b%2-b%4\2)/50

These couple of changes get you down to 266.

P#79270 2020-07-13 18:20 ( Edited 2020-07-13 18:28)

Haha wow that's impressive! I was hoping to improve the turning code but couldn't think how, that's a really clever take on it, down to 265 chars

P#79271 2020-07-13 18:29
1

Just because, here's a version that's 280 chars that updates the score in super modern real time and also outputs it at the end, thanks to Jade for the extra savings!

d={}u=0w=0y=4x=4p=print
cls()::_::b=btn()w+=(b%2-b%4\2)/50
x+=cos(w)/.7y+=sin(w)/.7if(2<pget(x,y)or u<1)p(u,0)u+=1circ(l,m,2,0)l=rnd(99)m=rnd(99)
if(pget(x,y)>1)p(u)()
add(d,{x,y,2,u})for e in all(d)do e[4]-=.1pset(unpack(e))
if(e[4]<0)e[3]=1
end
circ(l,m,2,3)
?u,0,0
flip()goto _
P#79272 2020-07-13 18:34 ( Edited 2020-07-13 19:27)
1

Not quite sure if it might cause any issues if the value isn't exactly 1.5, but you can also save 2 characters by using this approximation (equal to x1.43)

x+=cos(w)/.7y+=sin(w)/.7

also, you can use this print shortcut for the score, as long as nothing else is on the same line:

?u,0,0

(super cryptic, yet really helpful)

P#79274 2020-07-13 18:39 ( Edited 2020-07-13 18:41)

Oh that's clever too, no particular reason for 1.5 other than I needed it to be fast enough to not instantly overlap with a tail piece.

P#79276 2020-07-13 19:23

@ChrisM It still felt wrong that I had removed del - it didn't change the graphic effects when I did, but it did mean the table kept growing.

I performed a quick test plus estimate of how long it would take to fill the pico-8 memory, and estimated about 12 minutes - in practice (I left it running while I did other stuff) it crashed after 27 minutes - either a bad quick estimate or the performance suffered leading to slowdown as the table grew.

If you want the game to last longer, see if you can add del back in. If 27 minutes is fine, don't worry about this comment.

Separate from that, another thing - that you might already know - is that screen wraps can be written concisely with code such as x%=128 y%=128

Wrapping the screen would increase the probability of a snake crashing into itself, thus shortening the game - with the proviso that the user is trying to eat apples and thus lengthening the snake (otherwise the snake stays small and the probability it crashes into itself may be 0).

If you did include screen wraps, then 128 could be assigned to a variable, which would allow it to be used for generation of apple position as well. In characters, there is an increase of about 13 characters for the screen wrap and changing the apple position generation code to use the same variable.

@JadeLombax good improvements!

P#79297 2020-07-14 07:45 ( Edited 2020-07-14 07:46)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-04-18 03:47:37 | 0.028s | Q:35