Skip to content

Instantly share code, notes, and snippets.

@atimb
Forked from 140bytes/LICENSE.txt
Created December 8, 2011 23:32
Show Gist options
  • Star 29 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save atimb/1449250 to your computer and use it in GitHub Desktop.
Save atimb/1449250 to your computer and use it in GitHub Desktop.
Snake game in 140byt.es

Snake game in 140byt.es

A working demo.

A basic snake game as an entry to the 140byt.es contest in 136 chars / 138 bytes.

Credit goes to the JS ASCII Logo for the ASCII rendering engine :), and the whole community for the great minifying tips.

function(
a, // The array containing the points of the snake
b, // The next step snake head should move to
c, // The apple position
d, // The size of the level
e // Just declaration
) {
a.unshift(b); // Move the head of the snake forward
c^a[0]&&a.pop(); // If we don't hit apple, decrement snake tail
for(b=d*d;b--;) // Loop through level
e=[e]+"■ "[!~a.indexOf(b)&b!=c]+["\n"[b%d]]; // Put space or snake(or apple) body, and line end if needed
return~a.indexOf(a[0],1)||e // Return rendered level as string, or a number if game is over
}
function(a,b,c,d,e){a.unshift(b);c^a[0]&&a.pop();for(b=d*d;b--;)e=[e]+"■ "[!~a.indexOf(b)&b!=c]+["\n"[b%d]];return~a.indexOf(a[0],1)||e}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2011 Attila Incze <http://atimb.me>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
{
"name": "snakeGame",
"description": "A basic snake game rendered in ASCII",
"keywords": [
"ascii",
"snake",
"game"
]
}
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Snake</title>
<style>
#snake {
font-family: "Courier New", monospace;
color: #F0DB4F;
background: #323330;
display: inline-block;
white-space: pre;
line-height: 9px;
font-size: 15px;
}
</style>
</head>
<body>
<div id="snake"></div>
<script>
var snake =
function(a,b,c,d,e){a.unshift(b);c^a[0]&&a.pop();for(b=d*d;b--;)e=[e]+"■ "[!~a.indexOf(b)&b!=c]+["\n"[b%d]];return~a.indexOf(a[0],1)||e};
(function(){
var size = 30;
var oldstep, step = -1;
document.onkeydown = function(e) {
var keyCode = (e || window.event).keyCode,
nextstep = [1,size,-1,-size][keyCode-37]; // Bind arrows to change snake direction
step = (nextstep == -oldstep) ? oldstep : nextstep; // Don't enable to turn Pi/2
}
var center, apple = center = size*(size*.5+.5); // Init apple to middle of level
var f,snakie = (f=function(c,i){return i?f(c,--i).concat(c):[]})(center,5); // Fancy fn to create snakie = [center,center,..] with length = 5
(function() {
var oldlength = snakie.length, next = (snakie[0]+(oldstep=step)+size*size)%(size*size),
game = snake(snakie, next, apple, size);
if (typeof game === "number") { // Snake hit himself: Print Game Over centered
document.getElementById( "snake" ).innerHTML += (f=function(i){return i?f(--i)+" ":""})(size*.5-5) + "Game Over";
} else {
document.getElementById( "snake" ).innerHTML = game; // Print the level
setTimeout(arguments.callee, 100); // loop the game
}
if (snakie.length !== oldlength) {
while (~snakie.indexOf(apple)) {
apple = Math.floor(Math.random()*size*size); // reposition apple, if it was consumed
}
}
})();
})();
</script>
</body>
@aemkei
Copy link

aemkei commented Dec 11, 2011

Nice work and thanks for the credits!
BTW: Use this link to bypass the iframe issue: http://jsfiddle.net/atimb/AUGax/show/

@aemkei
Copy link

aemkei commented Dec 11, 2011

And how about using a[b] instead of a.indexOf(b)?

@maettig
Copy link

maettig commented Dec 12, 2011

@aemkei, don't mix indexOf with charAt. ;-) @atimb, I like how you turn the keyCode into a direction using an array. I will try to add this to my Pac-Man game. To bad there is no collision detection. Here are some simple ideas: Add something like var nextStep = [1, size, -1, -size][keyCode - 37]; if (nextStep != -step) step = nextStep; so it's not possible to turn the snake by 180 degree any more. And replacing a[0]+b with (a[0]+b+d*d)%(d*d) (which should be golfed down, obviously) would make the snake flip to the other edge of the playground if leaving at the top or bottom.

@atimb
Copy link
Author

atimb commented Dec 17, 2011

@aemkei a[b] can turn out to be a great idea.
Let's suppose we store the level+snake(+maybe apple) in one size*size array. Let's have a mapping, for example snake from head to tail is +n, +n-1, ... +2, +1, while 0 and negative numbers stands for the empty place. In every round we set the value of the field of the snake head to +n (snake length), and decrement the WHOLE array (except if apple was just picked up). In the end, use replace to generate the HTML content from this array directly.

For now, I've updated the code according to the suggestions of @aemkei and @maettig. Unfortunately a small part of logic is living outside the 140bytes, otherwise it would not fit. Now we have collision detection, Pi/2 turnaround protection and top-bottom continuity.

@tsaniel
Copy link

tsaniel commented Dec 17, 2011

Replace
return ~a.indexOf(a[0],1)||e
with
return~a.indexOf(a[0],1)||e

@atimb
Copy link
Author

atimb commented Dec 18, 2011

Great, updated!

@arnorhs
Copy link

arnorhs commented Mar 31, 2013

it looks like there's a tiny bug. if you move the snake to the right off the screen, it will appear on the other side one square down. was this on purpose maybe?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment