[Question]
  [
## Games are fun
This Code Golf here was so fun I had to make a version for other classic games similar in complexity: [Shortest Way of creating a basic Space Invaders Game in Python](https://codegolf.stackexchange.com/questions/4410/shortest-way-of-creating-a-basic-space-invaders-game-in-python)
This time, however, try to recreate the classic 'Snake' game, in which you start out as a small shape, constantly moving to collecting pieces to increase your score. When you collect a piece, your 'tail' grows, which follows the path you have made. The objective is to last the longest without crashing into your own tail, or into the walls
Qualifications:
* You, the characters that make up the tail, the walls, and the pieces you collect should all be different characters
* Show a HUD with the score. The score increases by 1 point for each piece you collect
* The player loses when they collide with their own tail or the wall
* A piece spawns in a random area immediately after a piece is collected, not to mention at the start of the game
* Speed of the game doesn't matter, as long as it is consistent
* ~~The 'cells' should be 2x1 characters, since the height of block characters is ~twice the width~~ Can be 1x1, because 2x1 is just ugly and I didn't really think of that
* The keys for changing the direction should be `awsd`, left, up, down, right respectively
* The starting direction should always be up
* You must show the edges of the wall. The score may overlap the wall
Shortest code that meets the above criteria wins. Imaginary Bonus Points for creativity.
  
[Answer]
## JavaScript (~~553~~ 512 bytes)
[Link to playable version](http://copy.sh/snake/)
  
```
c=0;a=b=d=-1;e=[f=[20,7],[20,8]];i=Math.random;~function n(){if(c&&(87==a||83==a
))c=0,d=87==a?-1:1;if(d&&(65==a||68==a))d=0,c=65==a?-1:1;p([j=e[0][0]+c,k=e[0][1
]+d])||!j||39==j||!k||10==k?b+=" | GAME OVER":(e.unshift([j,k]),p(f)?(f=[1+38*i(
)|0,1+9*i()|0],b++):e.pop());for(m=h="";11>h;h++){for(g=0;40>g;g++)l=g+","+h,m+=
!g||39==g||!h||10==h?"X":e[0]==l?"O":p(l)?"*":f==l?"%":" ";m+="\n"}x.innerHTML=m
+b;!b.sup&&setTimeout(n,99)}();onkeydown=function(o){a=o.keyCode};function p(o){
return e.join(p).indexOf(p+o)+1}
```
I tried to make it output to the real console at first (with `console.log` and `console.clear`), but it was flickering too much, so I put it into console-like HTML. It will work with this:
```
<pre id=x>
```
Also I implemented it with 2x1 cells first, but it just looked worse than 1x1. That would be a minor change though.
Uses `awsd` keys on keyboard.
**Update:**
I was able to cut it down to 512 (exactly 0x200) bytes by improving the tail search and doing some more magic.
You now get 2 points when a piece spawns in your tail (it's a feature). I also fixed the overlapping when the snake bites itself.
[Answer]
**16 bit 8086** 
526 bytes / 390 bytes
Decode this using [a Base64 decoder](http://www.opinionatedgeek.com/DotNet/Tools/Base64Decode/default.aspx) and call it "snake.com" then execute from Windows command prompt. Tested on WinXP, you may need to use DosBox to get the right video mode. Control keys are 'wasd' and space to exit. Press 'w' to start.
```
uBMAzRC5AD+2AOipAb1AAbgAoI7Auf//v4sMsAHzqrgAtLksAfOqg8cU/sx19OgsAYs+8gKwAuj4
ALQAzRpCiRYOA4kWEAPouAC0C80hCsB0IbQIzSG+ygKDxgOAPAB0EjgEdfSLRAGzAP/Qo1cBiB7w
AulqAIEGdAGu/7P+uNECgMMEw7MCuNsCgMMGw4s+8gKLHvACisPolwADv+YCJoo16I0AiT7yAoD+
A775AnREiz70AiaKHbAA6HUAA7/mAok+9AKA/gB0FscGVwHNAoEudAGu/zPJtj/o2QDofQC0AM0a
OxYOA3X2/wYOA+lZ/8YEAE7+BIA8CnT16F4AaOAB6EQAM9K5LQD38YvCweACBQoA9+WL+OguALlL
ADPS9/HB4gKDwgsD+iaAPQB10rADiMRXq4HHPQGrq4HHPAGrq4HHPQGrX8OhEAO62wD34rntf/fx
iRYQA4vCw772Ar8K9bUEshCstACL2AHDi4f6ArMDtwXR+LEAwNEC/smA4Q8miA0p7/7PdevoIQA6
xHQE/st13ugKAP7NdcroAwB1+8O3BSbGBQEp7/7PdfaBx0EG/srDuBAQM9uAwwLNEID7CnX2w7gD
AM0QzSB3dgEgxgIAYYcBZIUBIMYCAHd8AXN+ASDGAgAA+wAF/P8EAAIAH4ofigAAAADRxeD/TJlO
gQPvQrVA4++BVdVjgQ==
```
Here's a character mode version that's 390 bytes long:
```
uAMAzRC4ALiOwLlQADP/uCCf86uzF6u4AA+xTvOruCCfq7LdfCxUPOr6BgBiz5+AqF8Aqu0AM0aQ
okWhgKJFogC6MUAtAvNIQrAdCG0CM0hvlYCg8YDgDwAdBI4BHX0i0QBswD/0KNSAYgefALpdgCBB
m8Bov+z/rhdAoDDBMOzArhnAoDDBsOLPn4Cix58AiaJHQOclgmijUmiR2JPn4CgP4DvoUCdFOLPo
ACJoodJscFAAADv3JYiT6AAoD+AHQkxwZSAVkCgS5vAaL/vwEAudAHJoA9qnUEJsYFzIPHAuLx6F
4AtADNGjsWhgJ19oMGhgIC6Uz/xgQATv4EgDwKdPXoPgBo5wHoIgC5FwD38Wn6oADoFgC5TgD38U
ID0gP6JoA9AHXhJscFA93DoYgCutsA9+K57X/38YkWiAKLwjPSw76CAr8CALkEALSfrAQwq+L6w8
0gd3EBIFcCAGGCAWSAASBXAgB3dwFzeQEgVwIAYP+gAP7/AgACqtAH0AcAAAAA
```
This character mode one's three bytes longer (but the snake's better):
```
uAMAzRC4ALiOwLlQADP/uCCf86uzF6u4AA+xTvOruCCfq/7LdfCxUPOr6BsBiz6BAibHBQEKtADN
GkKJFokCiRaLAujHALQLzSEKwHQhtAjNIb5ZAoPGA4A8AHQSOAR19ItEAbMA/9CjUwGIHn8C6XgA
gQZwAaD/s/64YAKAwwTDswK4agKAwwbDiz6BAosefwImiR0Dv3VYJoo1JscFAQqJPoECgP4DvogC
dFOLPoMCJoodJscFAAADv3VYiT6DAoD+AHQkxwZTAVwCgS5wAaD/vwEAudAHJoA9qnUEJsYFzIPH
AuLx6F4AtADNGjsWiQJ19oMGiQIE6Ur/xgQATv4EgDwKdPXoPgBo6gHoIgC5FwD38Wn6oADoFgC5
TgD38UID0gP6JoA9AHXhJscFA93DoYsCutsA9+K57X/38YkWiwKLwjPSw76FAr8CALkEALSfrAQw
q+L6w80gd3IBIFoCAGGDAWSBASBaAgB3eAFzegEgWgIAYP+gAP7/AgACqtAH0AcAAAAA
```
[Answer]
## shell/sh, 578 chars
I tried to be POSIX compliant (being as much portable as possible and avoid bashisms, even the random-number-generator does not need /proc). You can e.g. play it in your native terminal or via a SSH-session: run with 'dash -c ./snake'
There is also an unuglyfied/readable variant in ~2800 bytes, which can be seen [here](https://github.com/bittorf/shell_snake).
Some notes:
shell-scripting is not suited for coding games 8-)
* to be fair, we only used so called 'builtins', which means:
	+ no external calls of programs like 'clear', 'stty' or 'tput'
	+ because of that, we redraw the whole screen on every move
	+ the only used builtins (aka native commands) are:
		- echo, eval, while-loop, let, break, read, case, test, set, shift, alias, source
* there is no random number generator (PRNG), so we have to built our own
* getting a keystroke blocks, so we have to spawn another thread
	+ for getting the event in parent-task we use a tempfile (ugly!)
* the snake itself is a list, which is cheap:
	+ each element is a (x,y)-tuple
	+ loosing the tail means: shift the list by 1
	+ adding a (new) head means: append a string
* the grid is internally an array, but shell/sh does not know this:
	+ we "emulated" array(x,y) via an ugly eval-call with global vars
* and finally: we had a lot of fun!
```
#!/bin/sh
alias J=do T=let E=echo D=done W=while\ let
p(){ eval A$1x$2=${3:-#};}
g(){ eval F="\${A$1x$2:- }";}
r(){
E $((1+(99*I)%$1))
}
X=9
Y=8
L="8 8 $X $Y"
I=41
W I-=1
J
p $I 1
p $I 21
p 1 $I
p 41 $I
D
p 3 3 :
>L
W I+=1
J
E -ne \\033[H
y=22
W y-=1
J
Z=
x=42
W x-=1
J
g $x $y
Z=$Z$F
D
E "$Z"
D
E $B
. ./L
case $D in
a)T X+=1;;d)T X-=1;;s)T Y-=1;;*)T Y+=1;;esac
g $X $Y
case $F in
\ |:)p $X $Y O
L="$L $X $Y"
case $F in
:)W I+=1
J
x=`r 39`
y=`r 19`
g $x $y
[ "$F" = \  ]&&{
p $x $y :
break
}
D
T B+=1;;*)set $L
p $1 $2 \ 
shift 2
L=$@;;esac;;*).;;
esac
D&
while read -sn1 K
J
E D=$K>L
D
```
![enter image description here](https://i.stack.imgur.com/0AEY1.png)
[Answer]
### C# .NET Framework 4.7.2 Console (~~2,456~~ ~~2,440~~ ~~2,424~~ ~~2,408~~ ~~2,052~~ ~~1,973~~ ~~1,747~~ 1,686 bytes)
This was fun, but I really had to think what variables were what, because they are only one letter.
```
using m=System.Console;using System;using System.Collections.Generic;using System.Threading;class s{static void Main(){m.CursorVisible=0>1;new s()._();}int l;Action<string> w=(x)=>m.Write(x);Action<int,int>n=(x,y)=>m.SetCursorPosition(x,y);(int x,int y)d,c,a;int h,u;List<(int x,int y)>p;void _(){while(1>0){f();h=25;u=25;p=new List<(int x,int y)>();l=0;d=(0,-1);c=(u/2,h/2);e();m.SetWindowSize(u+4,h+4);m.SetBufferSize(u+4,h+4);while(1>0){k();if(t())break;g();r();}f();m.SetWindowSize(u+4,h+6);m.SetBufferSize(u+4,h+6);n(1,h+3);w("        Game over,\n   press any key to retry.");f();m.ReadKey(1>0);m.Clear();}}private bool t(){if(c.x<0||c.y<0||c.x>=u||c.y>=h){r();n(c.x+2,c.y+2);w("X");return 1>0;}for(i=0;i<p.Count;i++){for(int j=0;j<i;j++){if(p[i].x==p[j].x&&p[i].y==p[j].y){r();n(c.x+2,c.y+2);w("X");return 1>0;}}}return 0>1;}private void e(){a=(z.Next(u),z.Next(h));l++;}void f(){while(m.KeyAvailable)m.ReadKey(1>0);}int i;void k(){var b=DateTime.Now;while((DateTime.Now-b).TotalMilliseconds<230)Thread.Sleep(10);if(!m.KeyAvailable)return;var a=m.ReadKey(1>0).Key;switch(a){case ConsoleKey.A:if(d.x==0)d=(-1,0);break;case ConsoleKey.W:if(d.y==0)d=(0,-1);break;case ConsoleKey.S:if(d.y==0)d=(0,1);break;case ConsoleKey.D:if(d.x==0)d=(1,0);break;}f();}void g(){c.x+=d.x;c.y+=d.y;p.Add((c.x,c.y));while(p.Count>l)p.RemoveAt(0);if(c.x==a.x&&c.y==a.y)e();}void r(){n(1,1);w("/");w(new string('-',u));w("\\");n(1,h+2);w("\\");w(new string('-',u));w("/");for(i=0;i<h;i++){n(1,i+2);w("|");n(u+2,i+2);w("|");}for(i=0;i<h;i++){for(int j=0;j<u;j++){n(i+2,j+2);w(" ");}}n(a.x+2,a.y+2);w("@");for(i=0;i<p.Count;i++){n(p[i].x+2,p[i].y+2);w("#");}n(2,0);w("Score:"+l);}Random z=new Random();}
```
Some screenshots:
[![Snake with score of 10](https://i.stack.imgur.com/X25F7.png)](https://i.stack.imgur.com/X25F7.png)
[![Snake crashed with score of 4](https://i.stack.imgur.com/Q09XC.png)](https://i.stack.imgur.com/Q09XC.png)
<no longer have binaries, you can compile yourself>
[Answer]
# Applesoft Basic - 478 (462)
This was my first ever code golf, but it was written back in 1989, and it mostly implements the snake game as requested (but without food, the snakes just continuously grow, and it's actually two players, not one) using only two lines of Applesoft Basic.
There were a number of two-line program contests at the time, such as in Dr. Dobbs journal. I spent 6 months figuring out how to fit this into two lines which have a limit of 255 characters (and only one branch)
More info at: <http://davesource.com/Projects/SpeedWaller/>
The program typed in is exactly two lines:
```
1ONSCRN(X,Y)<>7ANDB<>0ANDSCRN(U,V)<>7GOTO2:HOME:GR:X=10:Y=20:U=30:V=Y:I=201:J=202:K=203:M=205:W=215:A=193:S=211:Z=218:O=1:Q=-1:P=49152:COLOR=7:HLIN0,39AT0:HLIN0,39AT39:VLIN0,39AT0:VLIN0,39AT39:VTAB22: ?"WASZ IJKM  "C:ONB=0GOTO2:CALL-678:RUN
2PLOTX,Y:PLOTU,V:B=PEEK(P):G=B<>ZANDB<>W:H=B<>AANDB<>S:O=G*(O*H+(B=S)-(B=A)):L=H*(L*G+(B=Z)-(B=W)):G=B<>IANDB<>M:H=B<>JANDB<>K:Q=G*(Q*H+(B=K)-(B=J)):R=H*(R*G+(B=M)-(B=I)):X=X+O:Y=Y+L:U=U+Q:V=V+R:FORN=1TO99:NEXT:C=C+1:VTAB22:HTAB12:?C:GOTO1
```
The listing when formatted looks like this:
```
1 ONSCRN(X,Y)<>7 AND B<>0 AND SCRN(U,V) <> 7 GOTO 2: HOME : GR :
  X=10 : Y=20 : U=30 : V=Y : I=201 : J=202 : K=203 : M=205 : W=215 :
  A=193 : S=211 : Z=218 : O=1 : Q=-1 : P=49152 : COLOR=7 : HLIN 0,39
  AT 0 : HLIN 0,39 AT 39 : VLIN 0,39 AT 0 : VLIN 0,39 AT 39 : VTAB 22 :
  ? "WASZ IJKM  "C : ON B=0 GOTO 2 : CALL -678 : RUN
2 PLOT X,Y : PLOT U,V : B=PEEK(P) : G= B<>Z AND B<>W: H=B<>A AND B<>S :
  O=G*(O*H+(B=S)-(B=A)) : L=H*(L*G+(B=Z)-(B=W)) : G=B<>I AND B<>M :
  H=B<>J AND B<>K : Q=G*(Q*H+(B=K)-(B=J)) : R=H*(R*G+(B=M)-(B=I)) :
  X=X+O : Y=Y+L : U=U+Q : V=V+R : FOR N=1 TO 99 : NEXT : C=C+1 :
  VTAB 22 : HTAB 12 : ? C : GOTO 1
```
The game is actually *two players* and includes "instructions" at the bottom of the page showing the keys as well as a counter so you can see how many steps you survived. It's 478 characters, 16 of those are the instructions and counter output, so 462 if you want to shave those off.
[Answer]
# TI-Basic, 307 [bytes](https://codegolf.meta.stackexchange.com/a/4764/98541)
This one is very special to me, since I learned to program with a similar snake game on my TI-83+ (in high school, during boring classes). Also, on these calculators, golfing the programs was a real concern because of the limited space and performance
The controls are the direction keys, but they could easily be changed for `awsd` (although noone would want that since it's an `abc` layout)
codes for the keys would be: `A`: 41, `W`: 85, `S`: 81, `D`: 51
```
ClrHome
99→dim(ʟX
ʟX→Y
{8,16→dim([A]
For(X,1,16
For(Y,1,8
If X=1 or X=16 or Y=1 or Y=16
Then
Output(Y,X,":
1→[A](Y,X
End:End:End
8→X:7→Y:-1→V
Repeat [A](Y,X
1+I(I<99→I
Y→ʟY(I
X→ʟX(I
Output(Y,X,0
1→[A](Y,X
If X=N and Y=O or not(N
Then
Repeat not([A](O,N
randInt(2,7→O
randInt(2,15→N
End
Output(O,N,1
Output(1,1,S
S+1→S
Else
1+J(J<99→J
ʟY(J
Output(Ans,ʟX(J)," 
0→[A](Ans,ʟX(J
End
getKey→G
not(G)U+(G=26)-(G=24→U
not(G)V+(G=34)-(G=25→V
X+U→X:Y+V→Y
End
```
[![demo as gif](https://i.stack.imgur.com/lizob.gif)](https://i.stack.imgur.com/lizob.gif)
[Answer]
**Ruby 1.9 */Windows only/* (354 337 355 346 bytes)**
```
require'Win32API';G=(W=Win32API).new g="crtdll","_getch",t=[],?I
B=(c=?#*39+h="#
#")+((S=' ')*38+h)*20+c;n=proc{c while B[c=rand(800)]!=S;B[c]=?*;S}
n[h=760];k={97=>-1,100=>1,119=>d=-41,115=>41}
(B[h]=?O;system'cls';$><<B<<$.;sleep 0.1
d=k[G.call]if W.new(g,"_kbhit",[],?I).call>0
t<<h;B[h]=?o;B[h+=d]==?*?B[h]=n[$.+=1]:B[t.shift]=S)while B[h]==S
```
Plays in a 20x40 board in the windows console. The score is shown under the board.
Use `WASD` to control the snake, any other key to exit (forcefully!). Edit the sleep time at the end of line 5 to control the speed. *(Or save 10 characters and make it nearly unplayable by removing the sleep entirely!)*
Bonus feature: randomly fails to start (when initial piece is generated in snake's location).
I needed ~100 chars to work around the lack of a non-blocking getchar. Apparently Ruby 1.9.3 includes a "io/console" library which would have saved roughly half of those.
And this solution is Windows specific. There are published solutions to do the same type of thing in \*nix systems, but I haven't tested them to compare the character count.
Edit:
Had to add 18 bytes after I realized that the tail only grows after eating, not after each step. 
Edit 2: (Possibly) fixed crash issue, saved the 9 bytes by restricting to one food item.
[Answer]
# Python 3 - 644
```
from curses import *
import time
from collections import deque
from random import randrange as R
N,W,S,E=z=119,97,115,100
t=tuple
u=0,0
def m(s):
 a=lambda o,y,x:y.addch(o[0],o[1],x);q=lambda:(R(L-2),R(C-2));L,C=s.getmaxyx();curs_set(0);s.nodelay(1);s.border();s.refresh();r=newwin(L-2,C-2,1,1);n=deque();y,x=[L-2,0];d=N;n.append(u);c=N;p=q();a(p,r,N);a(u,s,48)
 while 1:
  if c in z:d=c
  if d==N:y-=1
  if d==S:y+=1
  if d==W:x-=1
  if d==E:x+=1
  l=n.pop()
  if (y,x) in n:return
  if (y,x)==p:p=q();a(p,r,N);n.append(l);s.addstr(0,0,str(len(n)))
  n.appendleft((y,x));a((y,x),r,S);a(l,r,32);r.refresh();time.sleep(.2);c=s.getch()
wrapper(m)
```
Does not quit cleanly. Piece might disappear if it spawns on top of the snake.
[Answer]
## Bash (too many characters: ca. 1522)
```
t=tput
tc="$t cup"
tr="$t rev"
ts="$t sgr0"
ox=5
oy=5
((w=$($t cols)-2-2*ox))
((h=$($t lines)-2-2*oy))
trap "$t rmcup
stty echo
echo 'Thanks for playing snake!'
" EXIT
$t smcup
$t civis
stty -echo
clear
printf -v hs %$((w+2))s
printf -v v "|%${w}s|"
$tc $oy $ox
printf %s ${hs// /_}
for((i=1;i<=h+1;++i)); do
$tc $((oy+i)) $ox
printf %s "$v"
done
$tc $((oy+h+2)) $ox
printf %s ${hs// /¯}
dx=0
dy=-1
hx=$((w/2))
hy=$((h-2))
l=2
xa=($hx $hx)
ya=($hy $((hy+1)))
$tr
for((i=0;i<${#xa[@]};++i)); do
$tc $((ya[i]+1+oy)) $((xa[i]+1+ox))
printf \ 
done
$ts
print_food() {
$tc $((fy+1+oy)) $((fx+1+ox))
printf "*"
}
nf() {
rf=1
while((rf))
do
rf=0
((fx=RANDOM%w))
((fy=RANDOM%h))
for ((i=0;i<${#ya[@]};++i))
do
if((ya[i]==fy&&xa[i]==fx))
then
rf=1
break
fi
done
done
print_food
}
nf
ps() {
s="SCORE: $l"
$tc $((oy-1)) $((ox+(w-${#s})/2))
printf "$s"
}
ps
while :
do
read -t 0.2 -s -n1 k
if (($?==0))
then
case $k in
w|W)((dy==0))&&{ dx=0;dy=-1;};;
a|A)((dx==0))&&{ dx=-1;dy=0;};;
s|S)((dy==0))&&{ dx=0;dy=1;};;
d|D)((dx==0))&&{ dx=1; dy=0;};;
q|Q)break;;
esac
fi
((hx=${xa[0]}+dx))
((hy=${ya[0]}+dy))
if((hx<0||hy<0||hx>w||hy>h))
then
go=1
break
fi
for((i=1;i<${#ya[@]}-1;++i))
do
if((hx==xa[i]&&hy==ya[i]))
then
go=1
break 2
fi
done
$tc $((ya[-1]+1+oy)) $((xa[-1]+1+ox))
printf \ 
$tr
$tc $((hy+1+oy)) $((hx+1+ox))
printf \ 
$ts
if((hx==fx&&hy==fy))
then
((++l))
ps
nf
else
ya=(${ya[@]::${#ya[@]}-1})
xa=(${xa[@]::${#xa[@]}-1})
fi
ya=($hy ${ya[@]})
xa=($hx ${xa[@]})
done
if((go))
then
$tc 3 3
echo GAME OVER
read -t 3 -s -n1
fi
```
![Screenshot](https://i.stack.imgur.com/eBtVd.png)
[Answer]
# Binary - ~~617~~ 274 Bytes
Base 64:
```
jtiO0LgAuI7AMf+50Ae4IAJg86u4//+5JgC/qALzq7kRAKtguSkAMcDzq7j//6thgceeAOLsuSYAv0oN86
thic+9BgDojADkYCR/PEh0HDxLdBM8TXQKPFB17IHHoADrDoPHBOsJg+8E6wSB76AAsAkmgD0HD5TEdAYm
gD0gdYCqT2AGHgeJ6UG+GH0B7on3R0f986T8B2FXiT4YfYD8AXQJi74YfbAgquskRUW/MAKDBhR9AaEUfb
MK9vOGxAQwqoPvA4jgMOQIwHXu6AQAX+l0/2Bmuf//AABm9/G5///38YnXgef/D4H/gAJ95on6g8Iog+oo
g/ooffiD+hJ91IHH0wDB5wImgD0JdMewB6phww==
```
Hex:
```
d88ed08e00b88eb831c0b9ff07d020b86002abf3ffb8b9ff0026a8bff302b9ab001160ab29b93100f3
c0b8abffff61abc781009eece226b9bf000d4aabf38961bdcf00068ce8e40024603c7f74483c1c744b
3c13744d3c0a755081eca0c7eb00830e04c709ebef83eb048104a0efb00026093d800f07c494067480
26203d80754faa0660071ee989be417d18ee01f7894747f3fdfca461078957183e807d01fc0974be8b
7d1820b0ebaa4524bf45023006837d14a1017d140ab3f3f6c486300483aa03efe088e430c008ee7504
e85f0074e960ffb966ffff0000f766b9f1fffff1f7d789e7810fffff810280e67dfa89c283832828ea
fa837d2883f812fad47dc78100d3e7c126023d807409b0c7aa07c361
```
Create a .com file from the above hex and run it in DOSBox.
Even though the qualifications says:
> 
> Speed of the game doesn't matter, as long as it is consistent
> 
> 
> 
You should use the command `cycles 1` if you want the game to be playable
There is also a version with no score which is 232 bytes
```
8ed88ed0b800b88ec031ffb9d007b8200260f3abb8ffffb92600bfa802
f3abb91100ab60b9290031c0f3abb8ffffab6181c79e00e2ecb92600bf
4a0df3ab6189cfbd0600e86c00e460247f3c48741c3c4b74133c4d740a
3c5075ec81c7a000eb0e83c704eb0983ef04eb0481efa000b00926803d
070f94c4740626803d207580aa4f60061e0789e941bee87c01ee89f747
47fdf3a4fc076157893ee87c80fc0174098bbee87cb020aaeb054545e8
03005feb9460b9ffff66f7f181e2ff0f81fa80027df089d783c22883ea
2883fa287df883fa127dde81c7d300c1e70226803d0974d1b007aa61c3
```
[Answer]
# JavaScript (Node) (348 bytes)
```
B=_=>s.includes(c=0|Math.random()*4)?B():c;E=i=>s.includes(i)?+(i==s[0
]):i^o?9:2;D=_=>console.log(I+`\n ##\n#${E(0)}${E(1)}#\n#${E(2)}${E(3)
}#\n ##`);o=B(s=[I=0]);f='w';process.stdin.setRawMode(1).on('data',k=>
f=k);setInterval(_=>D(s.includes(z=s[0]+{w:-2,s:2,a:-1,d:1}[f])|z<0|z>
3|s[0]+z==3&&process.exit(),s=[z,...s],z^o?s.pop():o=B(I++)),99);D()
```
Pretty is not a requirement, right? Or easy? Or big?
[![enter image description here](https://i.stack.imgur.com/lCzm6.png)](https://i.stack.imgur.com/lCzm6.png)
You start in the top-left corner of a 2x2 grid, facing up (so you better push "d" real quick). A "9" represents a background character, a "1" is the head of your snake, any "0"s are tails, and a "2" is a piece you're trying to collect.
Browser-playable version
```
// Mocking Node
process = {
  stdin: {
    setRawMode: () => ({
      on(_, callback) {
        addEventListener('keydown', e => callback(e.key))
      }
    })
  }
}
process.exit = () => {
  for (let i = 0; i < 9999; ++i) clearInterval(i)
  throw new Error('Game Over!')
}
// Allow restarting
document.getElementById('run')
  .addEventListener('click', () => {
    for (let i = 0; i < 9999; ++i) clearInterval(i)
    main()
  })
function main() {
  // The game
  B=_=>s.includes(c=0|Math.random()*4)?B():c;E=i=>s.includes(i)?+(i==s[0]):i^o?9:2;D=_=>console.log(I+`\n ##\n#${E(0)}${E(1)}#\n#${E(2)}${E(3)}#\n ##`);o=B(s=[I=0]);f='w';process.stdin.setRawMode(1).on('data',k=>f=k);setInterval(_=>D(s.includes(z=s[0]+{w:-2,s:2,a:-1,d:1}[f])|z<0|z>3|s[0]+z==3&&process.exit(),s=[z,...s],z^o?s.pop():o=B(I++)),99);D()
}
```
```
<button id=run>run</button>
```
A slowed-down version (A 99ms interval is pretty difficult)
```
// Mocking Node
process = {
  stdin: {
    setRawMode: () => ({
      on(_, callback) {
        addEventListener('keydown', e => callback(e.key))
      }
    })
  }
}
process.exit = () => {
  for (let i = 0; i < 9999; ++i) clearInterval(i)
  throw new Error('Game Over!')
}
// Allow restarting
document.getElementById('run')
  .addEventListener('click', () => {
    for (let i = 0; i < 9999; ++i) clearInterval(i)
    main()
  })
function main() {
  // The game
  B=_=>s.includes(c=0|Math.random()*4)?B():c;E=i=>s.includes(i)?+(i==s[0]):i^o?9:2;D=_=>console.log(I+`\n ##\n#${E(0)}${E(1)}#\n#${E(2)}${E(3)}#\n ##`);o=B(s=[I=0]);f='w';process.stdin.setRawMode(1).on('data',k=>f=k);setInterval(_=>D(s.includes(z=s[0]+{w:-2,s:2,a:-1,d:1}[f])|z<0|z>3|s[0]+z==3&&process.exit(),s=[z,...s],z^o?s.pop():o=B(I++)),499);D()
}
```
```
<button id=run>run</button>
```
You know you've won when you get a max-call-stack-exceeded error :).
If you want a version that's a little nicer to play, I also golfed a 3x3 version down to 381 bytes.
```
B=_=>s.includes(c=0|Math.random()*9)?B():c;D=_=>s.map((c)=>b[c]=+(s[0]
==c),b=[...1e9-1+''],b[o]=2)+console.log(I+`\n ##${b.map((h,i)=>i%3?h:
'#\n#'+h).join('')}#\n ###`);o=B(s=[I=0]);f='w';process.stdin.
setRawMode(1).on('data',k=>f=k);setInterval(_=>D(s.includes(z=s[0]+{w:
-3,s:3,a:-1,d:1}[f])|z<0|z>8|(z%3!=1&&s[0]%3+z%3==2)&&process.exit(),s
=[z,...s],z^o?s.pop():o=B(I++)),99);D()
```
Browser-playable version
```
// Mocking Node
process = {
  stdin: {
    setRawMode: () => ({
      on(_, callback) {
        addEventListener('keydown', e => callback(e.key))
      }
    })
  }
}
process.exit = () => {
  for (let i = 0; i < 9999; ++i) clearInterval(i)
  throw new Error('Game Over!')
}
// Allow restarting
document.getElementById('run')
  .addEventListener('click', () => {
    for (let i = 0; i < 9999; ++i) clearInterval(i)
    main()
  })
function main() {
  // The game
  B=_=>s.includes(c=0|Math.random()*9)?B():c;D=_=>s.map((c)=>b[c]=+(s[0]==c),b=[...1e9-1+''],b[o]=2)+console.log(I+`\n ##${b.map((h,i)=>i%3?h:'#\n#'+h).join('')}#\n ###`);o=B(s=[I=0]);f='w';process.stdin.setRawMode(1).on('data',k=>f=k);setInterval(_=>D(s.includes(z=s[0]+{w:-3,s:3,a:-1,d:1}[f])|z<0|z>8|(z%3!=1&&s[0]%3+z%3==2)&&process.exit(),s=[z,...s],z^o?s.pop():o=B(I++)),99);D()
}
```
```
<button id=run>run</button>
```
Slowed down version
```
// Mocking Node
process = {
  stdin: {
    setRawMode: () => ({
      on(_, callback) {
        addEventListener('keydown', e => callback(e.key))
      }
    })
  }
}
process.exit = () => {
  for (let i = 0; i < 9999; ++i) clearInterval(i)
  throw new Error('Game Over!')
}
// Allow restarting
document.getElementById('run')
  .addEventListener('click', () => {
    for (let i = 0; i < 9999; ++i) clearInterval(i)
    main()
  })
function main() {
  // The game
  B=_=>s.includes(c=0|Math.random()*9)?B():c;D=_=>s.map((c)=>b[c]=+(s[0]==c),b=[...1e9-1+''],b[o]=2)+console.log(I+`\n ##${b.map((h,i)=>i%3?h:'#\n#'+h).join('')}#\n ###`);o=B(s=[I=0]);f='w';process.stdin.setRawMode(1).on('data',k=>f=k);setInterval(_=>D(s.includes(z=s[0]+{w:-3,s:3,a:-1,d:1}[f])|z<0|z>8|(z%3!=1&&s[0]%3+z%3==2)&&process.exit(),s=[z,...s],z^o?s.pop():o=B(I++)),299);D()
}
```
```
<button id=run>run</button>
```
[Answer]
# [Haskell](https://www.haskell.org/), 579 bytes
```
import System.Process;import System.IO;p=('#'<$j)++"##\n";j=[0..20];r=fromEnum<$>withBinaryFile"/dev/urandom"ReadMode hGetChar;e(a,b)x|x=a|0<1=b;m s@(h@(x,y):t)d f=e(putStrLn"You Lost",do system"clear";putStr$foldr(++)p[show$length t,"\n",p,do y<-j;'#':[let z|elem(x,y)s='@'|f==(x,y)='F'|0<1=' 'in z|x<-j]++"#\n"];c<-hWaitForInput i 99;d<-e(getChar,pure d)c;a<-r;b<-r;let n|d>'s'=(x,y-1)|d>'r'=(x,y+1)|d>'a'=(x+1,y)|0<1=(x-1,y)in m(e(id,init)(h==f)$n:s)d$e((mod a 17+2,mod b 17+2),f)$h==f)$or[h`elem`t,x<0,y<0,x>20,y>20];main=hSetBuffering i NoBuffering>>m[(9,8)]'w'(9,8);i=stdin
```
[Try it online!](https://tio.run/##VVFtq9sgGP0rkgZUYnrb@2VrjaHcsY4Ldy@sH8boCtdWU@0SDWpu09H/3pkUBvugnCPnec45qLj/Lev6dtNNa10Am4sPspl@c/Ygvaf/vz5/pS1DcAKL9ISzLJlMfpmEnth2Np0@znbUscrZ5qPpmiItzzqoJ224u6x1LZMHId8eOseNsE3yXXLx2QoJ1CcZPijuqESc7HF/7Rm/zoo529MG@BVSK9STC14GLEDFJGq7sAnuxSQ/bQderA8JERb4MV5yqCV3Cb1r0srWwqEsw@3WK3tOa2mOQYFAkhiatMPcpchPNNZZbmsZwJ@rrGUz@nkGV/BaMTYyBtdwDAUB1Cbq@ji3G/rHTTt6KHL1g@uwtu7ZRHOgwWJBRZFLdLy3I23nJBD4QHmRO7ofrsHRXEUJPRxd8jkemLuz7M74wLJ5zDD6oz4fcMzQIIm0INrogJFirMKpWXosUolQYwXgYP4ueyQD3I8Qkyi5C63bqteh6msgfTEjl3j68jGCcvjEhmvD1EaGp66qpNPmGAt9sf9YWTZbtCDv8Q6e4QioZj4IbW63vw "Haskell – Try It Online")
[Answer]
# [C (gcc)](https://gcc.gnu.org/), 581 bytes
```
#define S++s;for(i=0,j=0;m[i][j];i=rand()%h)j=rand()%w;m[i][j]=2;
#define F for(i=0;i<h;++i){for(j=0;j<w;++j)
i,j,w=24,h=12;x=6,y=9;s;*t;c='w';
main(n){int m[h][w];for(memset(m,0,4*w*h);i<h;)*m[i++]=m[i][w-1]=1;for(srand(time(0));j<w;)j++[*m]=m[h-1][j]=1;m[y][x]=-1;S for(fcntl(0,4,2048);1;*t=-s){F n=m[i][j],putchar(n+s?n<0?'O':n-1?n-2?' ':'$':'#':'@');puts("");}printf("score:%d\n\n",s);usleep(200000);while(read(0,&n,1)+1)c=n-97&&n-'w'&&n-'s'&&n-'d'?c:n;c&2?y-=((c&4)-2)/2:(x-=(c&1)*2-1);t=m[y]+x;if(*t==2){S}else if(*t){puts("you died");break;}else F if(m[i][j]<0)++m[i][j];}}}
```
[Try it online!](https://tio.run/##NZJBr@IgEMfvforGt69lCmQLMbv7HEn35HUPHvt68FHc0rVoSk01xs/u0qokE2D4M/P7EzT/q/X9/laZnXUm2lDqcXfoiFUZa1SGbWHLoinRqm7rKgLvNTSv5fA6VRJnrwrr6Hkd7apGSi1cx8RYq1kNIdHAzLKGDUouWK2ExLP6wS7qAz2mPWqVDAnO2q11xMHVuj5qi7oshnLCak3rTU9alrFFOqQ1TF0gDSCUlmriGbgolZjkfiLtbWtIBjABQENpkbajtg7CkV4EH5eyOJeKC9xM/Dvt@j0JTZjMFr8ARWBT3MN1HTn1dM2Op17X24446nO3yvLkT7J0XOSOyzyJkmXyLcRbiN8JYBB7Mp8D3o5dcLUjc68PnVm@V5/u082ZBzz5vTFHIrNxAA613RvSmW0VQGLHBFABWjn@8TOOHQ/vNE3@MVVJrpcOdSzzC1eE6HgBXMJ3uSTnsNexgFRyAdir0S09o92RYEpJuG5uZu9NNCXg@iC9HE5RZU0ViL8Cwz98aNaj6vkAqwwofX2Q2@12v/8H "C (gcc) – Try It Online")
Some bytes can be saved by replacing variables `w` and `h` with fixed values, and characters `O @#$` with two-digits integers, but I prefer to keep it as it is in order to make it easier to customize.
]