[HN Gopher] Show HN: URL Snake
       ___________________________________________________________________
        
       Show HN: URL Snake
        
       Just a little demo I made of a fully functioning game of snake
       encoded entirely within a valid url (around 1033 bytes of code
       encoded into a 1464 byte url).
        
       Author : lbatchelor
       Score  : 104 points
       Date   : 2023-01-07 15:02 UTC (2 days ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | neontomo wrote:
       | I love these types of projects. A suggestion to take this a step
       | further is to encode it inside a QR code.
        
         | lbatchelor wrote:
         | That was actually the original plan! But unfortunately it seems
         | like my phone's qr code reader won't open it in a browser
         | automatically. I then tried using a url shortener to link to it
         | but absolutely no shortener that I could find would take a
         | data: url.
         | 
         | I could host my own shortener to do it, but it feels like that
         | is cheating the spirit of the challenge.
         | 
         | I'll keep playing with it though, add touch device controls,
         | maybe a site to allow generating different versions of the url
         | (different colours, sizes, game over messages, etc).
        
       | jstrieb wrote:
       | If you want to make clickable links with this code, you can use
       | URL Pages.
       | 
       | https://github.com/jstrieb/urlpages
       | 
       | It's a small JavaScript application to store entire web pages in
       | URLs. I made it after learning that links with data URLs are no
       | longer clickable.
        
         | calebegg wrote:
         | Shameless plug: my (free, ad-free) side project does this too:
         | https://codewich.com
        
       | lbatchelor wrote:
       | Can't update the post now, but I've actually got it down to 713
       | bytes, which I'm pretty happy with! I could remove
       | features/colors/styles at this point, but I think I'll leave it
       | there for now.
       | 
       | If anyone's interested, I've tried to annotate a fair amount of
       | the tricks I've used so far:
       | https://github.com/lukebatchelor/url-snake/blob/main/golf/de...
       | 
       | let e=document.body,t="Space: start/reset. Arrows:
       | Move<div><canvas id=a><style>#a{border:solid} _{background:tan} <
       | /style>",r=40,n=400,o,d=[[4,3]],s=d[0],c="#000",p=(e="red",t=n,a=
       | 0,l=a)=>{C[f="fillStyle"]=e,C.fillRect(a_r,l _r,t,t)},h=(e,t=n /2
       | ,a=t,l="center")=>{C[f]=c,C.textAlign=l,C.fillText(e,t,a)};e.inne
       | rHTML=t,C=a.getContext`2d`,a.height=a.width=n,C.font="30px f",e.o
       | nkeyup=({which:e})=>{36<e&&e<41?H=e-38:32!=e||o||(o=1,d=[[4,3]],H
       | =2,S=0)},setInterval(i=>{if(o){let[e,t]=d[0],a=e+H%2,l=t+(H-1)%2,
       | n=([e,t])=>e==a&&t==l;if(d.pop(),a<0||9<a||l<0||9<l||d.some(n))re
       | turn o=0,p(),h`:(`;d=[[a,l],...d],n(s)&&(d[++S]=d[S-1],s=[(D=new 
       | Date)%10,D_S%10]),p`tan`,d.map(e=>p(c,r,...e)),p(i,r,...s),h(S,9,
       | 30,"left")}},n);
        
         | Retr0id wrote:
         | Golfed to 697 bytes using a self-extracting webp/html polyglot:
         | data:text/html;base64,UklGRhgCAABXRUJQVlA4TAwCAAAvygIAAIU019bbN
         | spSFKWR9hdFZaqtb3rvM84/Q4AZ8bMlhCEF6nODpdXLmTVE9J9A0qbBtj+FIQ4I
         | tSvXD2Q5unN6D4zhrFElTYKWlecbTy1xFLz13m3bSfDTbSjX9eZVXiq7UW1Qa1S
         | v8pb3hl6dqcOd85r8pHWm1v3ocKfK+5V3a6snrGyf3xwDhuDxSQwWn8QxONA4nz
         | +BrCigRT2PCygxPIvjOIQGBWHoSYfAaEFhDAaVxFeH9/MlhsvamNlgEhZI8D4aO
         | P5RyUKNPJiRBwaWPVQoaOC+SUEhg8GwJMvkw0cCBZbwPmLa8VtTryyaRwq3tOOB
         | GJTspxTV1pL/cvvzBzK8RxWtiN87O+AuUr0AFVVUrypGFW1rzRXaAd9ZxjCLm12
         | wDIEiZ+9pv25QHLZVXVYT6gf37FlOl5eUP0lef0G6zl5MsvQUqetc1wmHyX+X+Y
         | IpzDCWPbTEX4d6G2VEja8O9VI4eTDEcwIujgdUSOMvFykY5LH4cp3IixQsiiMyi
         | a8IUV1eMqKZ1kuho8Y1QoLK4657mauuM8cEput01LoHElZKT7z2NnAYwwBZLSZi
         | MR26KDAFRFGkC7CilZeXQs/H49lQYHadDJ+aiw9oaRt8UEzyIonhw2h2kcSFhGb
         | Byi5ARw+qEYSvGlGCHyRISmhEfQzRSqjEDF5CFkNoaMmh7HuwcnpyAjxjYW52YX
         | MgaWQ9Yz48aW1nIG9ubG9hZD13aXRoKGMuZ2V0Q29udGV4dGAyZGApZm9yKHA9Z
         | T0nJztkcmF3SW1hZ2UodGhpcyxwLS0sMCksdD1nZXRJbWFnZURhdGEoMCwwLDEs
         | MSkuZGF0YVswXTspZSs9U3RyaW5nLmZyb21DaGFyQ29kZSh0KTtldmFsKGUpIHN
         | yYz0jPg==
         | 
         | (954 bytes of encoded URL)
         | 
         | Based on the technique used here:
         | https://gist.github.com/gasman/2560551
         | 
         | Edit: hm, at some point in my golfing I appear to have broken
         | the apple placement randomisation logic... I'm too lazy to
         | debug it right now (probably)
        
         | joering2 wrote:
         | But sometimes the new red element to eat is being placed on the
         | snake. Easier to spot after level 25.
        
       | planede wrote:
       | Some interesting features of this snake game:
       | 
       | 1. You can change directions multiple times within a tick, making
       | the last direction to be effective.
       | 
       | 2. You can change to any directions, including the opposite
       | direction of your current movement, which usually results in :(
       | as the snakes head bumps into its body...
       | 
       | 3. Except when the snake has length 1 or 2, then it's OK, as the
       | snake either does not have a body yet, or its body and head
       | switch places at the next tick.
       | 
       | As a combination of 1 and 2, quickly turning around is a risky
       | move.
        
       | gabrielsroka wrote:
       | Can't you just put the whole thing in a JavaScript URL without
       | using base64? Eg                 JavaScript:alert(1)
       | 
       | It would be shorter than 1464. I'm not at my computer right now
       | to try it...
       | 
       | Edit: It seems to work. Also, the original can be golfed some
       | more.
        
         | [deleted]
        
       | dang wrote:
       | Related ongoing thread:
       | 
       |  _How to store your app 's entire state in the url_ -
       | https://news.ycombinator.com/item?id=34312546 - Jan 2023 (88
       | comments)
        
       | [deleted]
        
       | hgsgm wrote:
       | HN doesn't linkify data: URLs
       | 
       | data:text/html;charset=utf-8,%3Cbody%3E%3Cscript%3Eeval(atob(%22b
       | GV0IGU9ZG9jdW1lbnQsdD1lLmJvZHkscj1NYXRoLGw9J1ByZXNzIHNwYWNlIHRvIH
       | N0YXJ0L3BhdXNlL3Jlc2V0LCBhcnJvdyBrZXlzIHRvIG1vdmU8YnI+PGJyPjxjYW5
       | 2YXMgaWQ9ImEiPjxzdHlsZT5jYW52YXN7Ym9yZGVyOiAxcHggc29saWQgYmxhY2s7
       | fWJvZHl7YmFja2dyb3VuZDojY2NjO308L3N0eWxlPicsaT00MCxvPTQwMCxuPW8sc
       | z0wLGY9MSxkPTAsYz0xLGg9MCxwPVtbMywzXSxbNCwzXSxbNSwzXV0sdT1wLHk9Wz
       | UsNV0sYj0iIzAwMCIsZz0oZSx0LHI9YixsPWksbz1pKT0+e1MuZmlsbFN0eWxlPXI
       | sUy5maWxsUmVjdChlLHQsbCxvKX0sdj0oZSx0LHIsbD0iY2VudGVyIik9PntTLmZp
       | bGxTdHlsZT1iLFMudGV4dEFsaWduPWwsUy5maWxsVGV4dChlLHQscil9LHg9ZT0+c
       | i5mbG9vcihyLnJhbmRvbSgpKmUpLGs9KCk9PntpZighZCYmIWMpe2xldFtlLHRdPX
       | AucG9wKCkscj1wWzBdWzBdK3MsbD1wWzBdWzFdK2Y7aWYocjwwfHw5PHJ8fGw8MHx
       | 8OTxsfHxwLnNvbWUoKFtlLHRdKT0+cj09ZSYmbD09dCkpcmV0dXJuIG0oKTtyPT15
       | WzBdJiZsPT15WzFdJiYoaCsrLHAucHVzaChbLi4ucFtwLmxlbmd0aC0xXV0pLHk9W
       | 3goOSkseCg5KV0pLHAudW5zaGlmdChbcixsXSksZygwLDAsIiNmZmYiLG4sbyk7Zm
       | 9yKFtlLHRdb2YgcClnKGUqaSx0KmkpO2coeVswXSppLHlbMV0qaSwiIzBmMCIpLHY
       | oIlNjb3JlOiAiK2gsbi05LDMwLCJyaWdodCIpfX0sbT0oKT0+e2M9MSxnKDAsMCwi
       | I2YwMCIsbixvKSx2KCJZb3UgZGllZCA6KCIsbi8yLG8vMil9LHc9KCk9PntjPTAsc
       | D1bLi4udV0scz0wLGg9MCxmPTF9LFM9KHQuaW5uZXJIVE1MPWwsYS5nZXRDb250ZX
       | h0KCIyZCIpKTthLmhlaWdodD1vLGEud2lkdGg9bixTLmZvbnQ9IjMwcHggQXJpYWw
       | iLGUuYWRkRXZlbnRMaXN0ZW5lcigia2V5dXAiLGU9PntlPWUud2hpY2g7Mzc9PWUm
       | JihzPS0xLGY9MCksMzg9PWUmJihzPTAsZj0tMSksMzk9PWUmJihzPTEsZj0wKSw0M
       | D09ZSYmKHM9MCxmPTEpLDMyPT1lJiYoYz93KCk6ZD1kPzA6MSl9KSxzZXRJbnRlcn
       | ZhbChrLG4pOw==%22))%3C%2Fscript%3E
        
         | bmacho wrote:
         | https://news.ycombinator.com/formatdoc says that between angles
         | it should work, but it does not. Or i don't know how to use it,
         | it doesn't seem to do anything.
         | 
         | <data:text/html;charset=utf-8,%3Cbody%3E%3Cscript%3Eeval(atob("
         | bGV0IGU9ZG9jdW1lbnQuYm9keSx0PSJTcGFjZTogc3RhcnQvcmVzZXQuIEFycm9
         | 3czogTW92ZTxkaXY+PGNhbnZhcyBpZD1hPjxzdHlsZT4jYXtib3JkZXI6c29saW
         | R9KntiYWNrZ3JvdW5kOnRhbn08L3N0eWxlPiIscj00MCxuPTQwMCxvLGQ9W1s0L
         | DNdXSxzPWRbMF0sYz0iIzAwMCIscD0oZT0icmVkIix0PW4sYT0wLGw9YSk9PntD
         | W2Y9ImZpbGxTdHlsZSJdPWUsQy5maWxsUmVjdChhKnIsbCpyLHQsdCl9LGg9KGU
         | sdD1uLzIsYT10LGw9ImNlbnRlciIpPT57Q1tmXT1jLEMudGV4dEFsaWduPWwsQy
         | 5maWxsVGV4dChlLHQsYSl9O2UuaW5uZXJIVE1MPXQsQz1hLmdldENvbnRleHRgM
         | mRgLGEuaGVpZ2h0PWEud2lkdGg9bixDLmZvbnQ9IjMwcHggZiIsZS5vbmtleXVw
         | PSh7d2hpY2g6ZX0pPT57MzY8ZSYmZTw0MT9IPWUtMzg6MzIhPWV8fG98fChvPTE
         | sZD1bWzQsM11dLEg9MixTPTApfSxzZXRJbnRlcnZhbChpPT57aWYobyl7bGV0W2
         | UsdF09ZFswXSxhPWUrSCUyLGw9dCsoSC0xKSUyLG49KFtlLHRdKT0+ZT09YSYmd
         | D09bDtpZihkLnBvcCgpLGE8MHx8OTxhfHxsPDB8fDk8bHx8ZC5zb21lKG4pKXJl
         | dHVybiBvPTAscCgpLGhgOihgO2Q9W1thLGxdLC4uLmRdLG4ocykmJihkWysrU10
         | 9ZFtTLTFdLHM9WyhEPW5ldyBEYXRlKSUxMCxEKlMlMTBdKSxwYHRhbmAsZC5tYX
         | AoZT0+cChjLHIsLi4uZSkpLHAoaSxyLC4uLnMpLGgoUyw5LDMwLCJsZWZ0Iil9f
         | SxuKTs="))%3C%2Fscript%3E>
        
       | rpastuszak wrote:
       | Hey I think you might like my Pong in a tweet then!
       | 
       | https://twitter.com/rafalpast/status/1316836397903474688?s=4...
       | 
       | Still waiting for VCs to invest in my Twitter as a CDN:
       | 
       | https://twitter.com/rafalpast/status/1316841669451558913?s=4...
       | 
       | The article from the tweet: https://laconic-
       | mu.vercel.app/index.html?c=eJylWOuS27YV%2Fu%...
        
       | lbatchelor wrote:
       | Edit: I've actually managed to get the javascript down to a
       | measly 859 bytes now. Pretty happy with some of the code golfing
       | techniques I came up with
        
         | gabrielsroka wrote:
         | You should be able to change
         | e.addEventListener("keyup"...
         | 
         | to                 e.onkeyup=...
         | 
         | but I haven't tested it.
        
           | lbatchelor wrote:
           | Ooh! Don't know how I missed that, I'll give it a go! Cheers!
        
       | tsukurimashou wrote:
       | Here is one I did a while ago, this is the colored version (so
       | not the smallest) Still under 1024bits which was my goal
       | 
       | <pre style="letter-spacing:8"id="A"><script>Y=200;P='o';J='
       | ';N=15;C='#';E='+';m=[];X=C.repeat(N+2);for(T in X)m[T]=C+J.repea
       | t(N)+C;m[0]=m[0].slice(0,-2)+E+C;m.unshift(X);m.push(X);function
       | s(a,b,c){return a.substring(0,b)+c+a.substring(b+1)}function
       | f(){e=setInterval(function w(){if(!z){R=p.length-1;if(h=p[R][0],j
       | =p[R][1],h=1==d?h-1:h,h=-1==d?h+1:h,j=2==d?j-1:j,j=-2==d?j+1:j,p.
       | push([h,j]),g=p.length-1,l=m[h][j],r){if(J!=l)if(E==l){x=y=0;for(
       | t++,k=1;J!=m[x][y];)with(Math)x=~~(random() _N+2),y=~~(random()_
       | N+2);m[x]=s(m[x],y,E);Y-=5}else z=1,P='x';!k&&t<g&&(b=p[g-t],m[b[
       | 0]]=s(m[b[0]],b[1],J)),k=0}for(a='',i=0;i<t;i++)i<g+1&&(b=p[g-i],
       | m[b[0]]=s(m[b[0]],b[1],P));for(b in m){for(K in m[b])H=m[b][K],a+
       | =H.fontcolor(/\\#/.test(H)&&"#03B"||/\w/.test(H)&&"#2B2");a+="\n"
       | }A.innerHTML=a}return w}(),Y)}t=3,p=[[1,1]];var i,z,r,k,d;f(),win
       | dow.addEventListener("keydown",function(k){if(c=k.keyCode,-1!=[37
       | ,38,39,40].indexOf(c))with(Math)D=1==abs(39-c)?39-c:2*(38-c),z||a
       | bs(D)!=abs(d)&&(d=D,clearInterval(e),f(),r=1)});</script>
        
       | nathell wrote:
       | My initial interpretation of the title was something that
       | _displays_ the game inside the URL, using Unicode block
       | characters.
        
         | lbatchelor wrote:
         | I think it was changed by mods unfortunately :/
        
       | realYitzi wrote:
       | And ChatGPT can tell that it's a game of Snake from the URL.
       | https://www.tiktok.com/@y.i.t.z.i/video/7186055378977803521
       | 
       | "When decoded, the script appears to be a Snake game implemented
       | using JavaScript and the HTML5 canvas element. The script creates
       | an HTML page with a canvas element and adds event listeners for
       | arrow keys and space bar to control the game."
        
         | lbatchelor wrote:
         | Wow, that's actually impressive. Any idea how chat gpt would
         | know that? Surely it's not making the request for it and surely
         | it's not actually decoding any base64 right?
        
           | realYitzi wrote:
           | I can venture a guess, but gonna wait until I know what I'm
           | talking about.
           | 
           | Over here it decodes a js animated SVG
           | https://vt.tiktok.com/ZS8rcjhgg/ but made a few slight
           | mistakes.
        
           | kevinwang wrote:
           | I recall seeing that it's actually quite fluent in base64
        
           | londons_explore wrote:
           | You'd be right a good chunk of the time if you said it was a
           | snake game just by seeing that it was a data URL and had the
           | word 'canvas' in.
        
           | UweSchmidt wrote:
           | ChatGPT has probably seen plenty of half-baked
           | excercise/homework snake implementations on Github to tell
           | that this is another one of those.
           | 
           | (Yes, this is moving the goalposts and implying that true AI
           | is just over the horizon...)
        
         | [deleted]
        
         | IAmGraydon wrote:
         | Wow that's impressive. Is ChatGPT updating its model fast
         | enough that this repo could have been included or is it really
         | figuring out what this is from the code itself?
        
           | londons_explore wrote:
           | ChatGPT had it's last update on 15th Dec 2022, but the main
           | scrape of the web for training data was ~2020.
           | 
           | Try asking it about someone famous from 2021 and it usually
           | doesn't know.
        
       | danielgjackson wrote:
       | Nice! I made a 250-byte Snake game (265 as a URL) a few years ago
       | after spending _far_ too long code-golfing it:
       | 
       | https://danielgjackson.github.io/tinyjs#snake
       | 
       | ...and even a 224 byte version (240 as a URL), but with a few too
       | many sacrifices.
        
         | lbatchelor wrote:
         | You are on a completely different level. Wow. I am going to
         | spend absolutely too long tomorrow trying to work out how on
         | earth you've done that. Cheers!
        
           | danielgjackson wrote:
           | It was spread over a long time, and quite painful to get
           | there!
           | 
           | If it's useful, I added an explanation of how it works at:
           | 
           | https://github.com/danielgjackson/tinyjs/blob/master/mini-
           | ex...
        
       | gernb wrote:
       | very cool!
       | 
       | here's several games in 280 characters or less
       | 
       | https://www.dwitter.net/h/game
        
       ___________________________________________________________________
       (page generated 2023-01-09 23:01 UTC)