SNE1K commented
Some time ago I made a snake game as small as possible (code golfing)
I ended up with [this](https://static.nani-so.re/showcase/snake)
Here is the commented version of my code
```js
<pre style="letter-spacing:8"id="A">
<!--
pre element can be minimized by removing spaces, removing the closing part (the browser will close it for us)
The double quotes around the id can also be removed
-->
<script>
Y=200;P='o';J=' ';N=15;C='#';E='+';m=[];
//Y being the initial interval time of the game (200ms)
//P is the default player character for the snake
//J is the default empty map character
//N is the inner map width and height
//C is the map border character
//E is the bonus character
//m is an empty array that will later contain the map
X=C.repeat(N+2);for(T in X)m[T]=C+J.repeat(N)+C;m[0]=m[0].slice(0,-2)+E+C;m.unshift(X);m.push(X);
//X=C.repeat(N+2); put in the variable 'X' the caracter from the variable 'C' N+2 times
//The X variable will be '#################' (15+2)
//for(T in X)m[T]=C+J.repeat(N)+C;
//a loop that will executes 17 times (length of the X variable) and append the m array with sub array containing the variable C (#) + the variable J ( ) N times (15) + the variable C (#) again
//m[0] to m[16] will contain '# #'
//m[0]=m[0].slice(0,-2)+E+C;
//this part will add a bonus at the end of the first item from the array by removing the last two characters and adding back the E variable (+) and the C variable (#)
//'# #' will become '# +#' this
//m.unshift(X);m.push(X);
//this part adds X (#################) at the begining of the array, shifting all other indexes by 1, and adding X again to the end of the array
//The final m is
//[
//['#################'],
//['# +#'],
//['# #'],
//['# #'],
//['# #'],
//['# #'],
//['# #'],
//['# #'],
//['# #'],
//['# #'],
//['# #'],
//['# #'],
//['# #'],
//['# #'],
//['# #'],
//['# #'],
//['# #'],
//['# #'],
//['#################'],
//]
function s(a,b,c){return a.substring(0,b)+c+a.substring(b+1)}
//function allowing to replace one character 'b' for a character 'c' in a string 'a'
function f(){e=setInterval(function w(){
//function f setting an interval stored in the e variable containing the w function
if(!z){R=p.length-1;
//if not z (z being the variable telling the game if the player is dead or not)
//p is an array containing all of the player positions as sub arrays (updating each inteval)
//R is the number of player moves
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){
//set all variables in if
//h=p[R][0]
//j=p[R][1]
//h and j are variables containing the last x and y player move
//h=1==d?h-1:h,h=-1==d?h+1:h,j=2==d?j-1:j,j=-2==d?j+1:j
//check where the player moved depending of the d (direction) variable and updates h and j with the new values
//p.push([h,j])
//push the new x and y coordonates calculated above
//g=p.length-1
//update g with the new player moves length
//l=m[h][j],r
//put the new player position map character in the variable l (to check later if the player stepped on a bonus, on a wall or on himself)
//finaly check if is true (==1) (r being the "ready" variable telling that the game started)
if(J!=l)
//if the player is not on an empty character
if(E==l){
//if player touches a bonus
x=y=0;
//intialize the x and y variables at 0
for(t++,k=1;J!=m[x][y];)
//for(t++,k=1,m[h]=m[h].replace(E,J);J!=m[x][y];)
//t++ will grow the snake tail by one
//k=1 means the tail just grown, will be useful later
//J!=m[x][y]; the last bit is just a while loop saying if m[x][y] doesn't match an empty space (J) then repeat the loop repeat itself (generating new x and y values until it finds a free space to put the new bonus)
with(Math)
//with(Math) will be useful to call random() without having to write Math.random() each time
x=~~(random()*N+2),y=~~(random()*N+2);
//put a random number within the map width and height
m[x]=s(m[x],y,E);Y-=5
//replace the empty space of the map chunk affected (m[x]) by the bonus character (using the s function)
//lower the interval time by 5ms
}
else
//else means the character where the player is, isn't a bonus or an empty character, mean the player hit himself or a wall
z=1,P='x';
//z=1 means game over
//P='x'; changes the player character to x (so the player knows the snake is dead)
!k&&t<g&&(b=p[g-t],m[b[0]]=s(m[b[0]],b[1],J)),k=0
//0==k if tail isn't growing
//&&t<g and tail size is inferior to player position array (means the player moved more time than the tail length)
//(b=p[g-t]
//set the b variable being the last player position after the tail length
//m[b[0]]=s(m[b[0]],b[1],J)
//replace the matching map positions to an empty character (it will clean after the snake, if we didn't do that, the snake would have an infinite tail)
//sets the k variable to 0 (to reset it if the tail was growing)
//if the tail was growing the last tail element wouldn't have been cleaned which would have make it grow by one
}
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)}
//the w function returns itself, this allows to immediatly start the game on the first call instead of having to wait for the first interval to complete
//Y is the interval time variable in ms (200 by default)
t=3,p=[[1,1]];var i,z,r,k,d;f(),
//t is the variable containing the intial snake tail length (3)
//p=[[1,1]] is the inital player position
//var i,z,r,k,d;f(), variable initialisation and lauching the f() function once
window.addEventListener("keydown",function(k){
//event listener on keydown
if(c=k.keyCode,-1!=[37,38,39,40].indexOf(c))
//storing keycode on the c variable
//if -1!=[37,38,39,40].indexOf(c) checking of the c variable is either 37, 38, 39 or 40 (up down left right arrows on keyboard)
with(Math)D=1==abs(39-c)?39-c:2*(38-c),z||abs(D)!=abs(d)&&(d=D,clearInterval(e),f(),r=1)});
//with(Math) allows to call abs without having to write down Math.abs each time
//D=1==abs(39-c)?39-c:2*(38-c),z||abs(D)!=abs(d)&&(d=D,clearInterval(e),f(),r=1)});
//short way to write:
// D=(abs(39-c)==1)?39-c:(38-c)*2;
// if(!z){
// if(abs(D)!=abs(d)) {
// d=D;
// clearInterval(e);
// f();
// r=1;
// }
// }
//which follow the rules:
//0 not moving
//1 = up
//-2 = right
//-1 = down
//2 = left
//it basically checks if the direction is the same or if the direction is on the same axis, if so do nothing, else update direction
//both the same direction and the same axis check are performed at the same time, since up / down are 1 and -1 and left / right are 2 and -2 I used Math.abs to obtain only positive numbers, it only has to check if abs(old_direction)!=abs(new_direction) are different to know if they aren't the same twice or on the same axis
//if the direction is updated, the interval is cleared to take the new direction immediatly instead of waiting for the next interval to allow for smooth controls
//it also puts the r variable at 1, the r variable tells if the game started or not (the first keypress on arrows will start the game)
```
if you wanna get into code golfing I recommend looking up some old examples of demo ([demoscene](https://en.wikipedia.org/wiki/Demoscene)), competitions (such as [js1k](https://js1k.com/)) as well as checking shorthand tricks for your language of choice.
finally fantasy consoles (like [pico8](https://www.lexaloffle.com/pico-8.php)) have some very good examples too
I have some resources about it [here](https://static.nani-so.re/links#code_golfing)
Peace