Tell me more ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Games are fun

this codegolf 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

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 an 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 didnt 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

share|improve this question
The snake isn't supposed to grow when eating? – leftaroundabout Jan 4 '12 at 0:18
hm? "When you collect a piece, your 'tail' grows, which follows the path you have made.", so yes, the snake grows. – Blazer Jan 4 '12 at 2:46

4 Answers

JavaScript (553 512 byte)

Link to playable version

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.

share|improve this answer
1  
beautiful! and you're right, it does look better as 1x1 than 2x1. the only worry I really had there was up and down being way faster than left and right but it's doable considering the constraints. The flashing in the console I don't mind so much (see my space invaders program, its fairly flickering) but I suppose a plain text web page works too! one qualm though... is there any way to restart without needing to refresh? :( – Blazer Jan 4 '12 at 5:24
Doesn't work with awsd – Neal Jan 4 '12 at 21:56
@Blazer That would take more 13 characters :-/ ... and you have the F5 key anyway. – copy Jan 5 '12 at 0:23
@Neal Yeah I used the arrow keys but fixed it now. – copy Jan 5 '12 at 0:24
@copy I suppose I didn't make it a requirement – Blazer Jan 5 '12 at 0:28
show 3 more comments

16 bit 8086

526 bytes / 390 bytes

Decode this using a Base64 decoder 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
share|improve this answer
points for creativity, but i think using dosbox is cheating because the challenge is to make the game work in an ascii console or terminal, not a dosbox. also, shouldn't code golf be source code, not binary? – Blazer Jan 5 '12 at 23:10
2  
@Blazer: That is the source code - I typed the machine code in using a hex editor - that's how l337 I am! ;-) The DosBox thing is only needed if your video drivers have trouble with mode 13 graphics (mine card is OK with it). It wouldn't be difficult to do an ascii version (probably smaller too) – Skizz Jan 6 '12 at 8:50
The "390-byte" version decodes to only 388 bytes and hangs when run under dosbox. Looks like something may have been lost in transmission. :( Still, the other two versions are extremely cool! – Ilmari Karonen Jan 6 '12 at 12:45

x86 Machine Code (128 bytes)

Much like my submission for Generating a Mandlebrot Fractal, I wrote a prod for the game of snake in 128 bytes. It doesn't fully meet the requirements of the challenge (it starts moving right, not all walls are drawn), but I'm posting it because I think it is an interesting and creative solution. The score is shown in binary on the right, the arrow keys control the direction of motion, the 'food' is dropped randomly, and it ends if you hit yourself, the wall, or the edge of the screen.

Link for executable and source code

Screenshot

Also, in regards to the earlier comment about whether dosbox is cheating, I think perfectly acceptable as long as it is in a text-based display mode, since then it is just a dos terminal.

share|improve this 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.

share|improve this answer
I like the idea of multiple food items at once, however there is a big problem: the tail should move with the player, only growing by one character for every piece of food you collect. – Blazer Jan 5 '12 at 23:08
You added the comment while I was working on fixing it... If there is only supposed to be one piece, I can remove the 9.times{}, saving 9 chars. – AShelly Jan 5 '12 at 23:43
the only requirement is that there be 1 or more piece of food at a time, so yes you could just make it 1 piece at a time, saving some characters – Blazer Jan 5 '12 at 23:49
the game randomly crashed on me at ~140 points, not sure why. but otherwise very nice – Blazer Jan 6 '12 at 2:32
Fixed the crash, I think. If it crashes again, please let me know the ruby error message. – AShelly Jan 28 '12 at 0:47

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.