Skip to content

Instantly share code, notes, and snippets.

@thingsinjars
Created February 4, 2012 22:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thingsinjars/1740736 to your computer and use it in GitHub Desktop.
Save thingsinjars/1740736 to your computer and use it in GitHub Desktop.
A True Tale of Love Lost and Found in an Infinite Number of Acts...
//Our little runner, celebration animation and placeholder
// for an empty set of possible maze generation steps
L="♥",
// q = current font size,
// z = width and generic constant,
// h = animation loop counter
q=z=h=21,
// All the colours we need,
// the hsla is pretty but tricky to shorten
b="#fff3#ffb3#4df3hsla(0,100%,84%,.1)".split(3),
// shorthand reference to a function we use more than once
o=setTimeout;
// set the size of the canvas (z^2)
c.width=c.height=441;
// The 'paint' function.
// d = array index (in b above), f and g are the x and y location to draw
i=function(d,f,g){
// to save having to write out 'a.textAlign, a.Baseline' etc...
with(a)
// Set the properties of the text on the canvas...
textAlign="center",
// ...these are annoyingly long.
textBaseline="middle",
// Sneaky trick: When setting the font size, you must also set the font family
// but rather than set 'Arial' (5 bytes), this tries to set a font called 'a' (1 byte).
// As that isn't available, it falls back to the system default
font=q+"px a",
// Set the colour using the array and index
fillStyle=b[d],
// Draw the current square
fillRect(z*f,z*g,z,z),
// Set the colour for the runner and the animation
fillStyle="red",
// Handy Evaluation Shortcut:
// the right-hand side of the OR is only evaluated if d is falsy (in this case 0)
// i.e. "only draw the text if this is the runner"
d||fillText(L,z*f+10,z*g+11)
};
// Our 'Solver' function
s=function(){
// Set previous step as 'visited'
n[y][x]=3;
// If this direction (South) is free
2>n[y+1][x]?
// Go here
(n[++y][x]=1,k.push(y,x)):
// Repeat for north
2>n[y-1][x]?
(n[--y][x]=1,k.push(y,x)):
// Repeat for west
2>n[y][x-1]?
(n[y][--x]=1,k.push(y,x)):
// Repeat for east
2>n[y][x+1]?
(n[y][++x]=1,k.push(y,x)):
// If there is no way forward from here, backtrack
(x=k.pop(),y=k.pop());
// Move the runner here
n[y][x]=0;
// If we've found our way to the goal
19==y&&19==x?
// Run the celebration animation
e(h=z):
// otherwise, setTimeout for our next animation/solution frame
o(s,50);
// For each row,
for(r in n)
// For each column,
for(l in n[r])
// Paint the square
i(n[r][l],l,r)
};
// The combination celebration and maze generation function
(e=function(){
// if there are steps left to complete in the animation
if(h--)
// Set the font size to get bigger
q=z*(z-h),
// Draw the celebration heart in the middle
i(0,10,10),
// Reset the original font size (for the trails)
q=z,
// setTimeout on this
o(e,40);
// If we're not animating, generate a maze
else{
// Empty array to keep track of where we've been
k=[];
// Loop through the existing maze and set everything back to being wall
for(n=[],y=z;0<y--;){
n[y]=[];
for(x=z;0<x--;)
n[y][x]=2
}
// Start top left
x=y=1;
// This is us
n[y][x]=0;
// Mark this square as corridor then loop while there is
// more corridor to carve
for(k.push(y,x);k.length;)
(
// Our stack of potential directions. To save space,
// this is done as a string but in order to be able
// to use numbers as directions, we set p to a string
// so we can concatenate.
p=L,
// We use steps of two for the maze so we can draw chunky walls
// If we aren't at the bottom edge and we're looking at a wall,
// South is a valid direction
18>y&&2==n[y+2][x]&&(p+=1),
// Repeat for North
2<=y&&2==n[y-2][x]&&(p+=2),
// Repeat for West
2<=x&&2==n[y][x-2]&&(p+=3),
// Repeat for East
2==n[y][x+2]&&(p+=4),
// While there are potential directions (i.e. our stack contains something)
p!=L)?
(
// Pick a random direction.
// If it is South...
1==(W=p[~~(Math.random()*p.length)])?
// ...clear the two squares south of here
n[++y][x]=n[++y][x]=1:
// Repeat for North
2==W?
n[--y][x]=n[--y][x]=1:
// Repeat for West
3==W?
n[y][--x]=n[y][--x]=1:
// Repeat for East
4==W&&(n[y][++x]=n[y][++x]=1),
// Add this to the stack of places we've been
k.push(y,x)
):
// Once we've got gone as far as we can, work our way back to continue generating
(x=k.pop(),y=k.pop());
// Put the goal at the bottom right
n[19][19]=0;
// Start solving
s(y=x=1)
}
})() // Kick it all off by running the animation as an immediately executing function
<!doctype html>
<html>
<head>
<title>JS1k, 1k demo submission [ID]</title>
<meta charset="utf-8" />
</head>
<body>
<canvas id="c"></canvas>
<script>
var b = document.body;
var c = document.getElementsByTagName('canvas')[0];
var a = c.getContext('2d');
document.body.clientWidth; // fix bug in webkit: http://qfox.nl/weblog/218
</script>
<script>
// start of submission //
L="♥",q=z=h=21,b="#fff3#ffb3#4df3hsla(0,100%,84%,.1)".split(3),o=setTimeout;c.width=c.height=441;i=function(d,f,g){with(a)textAlign="center",textBaseline="middle",font=q+"px a",fillStyle=b[d],fillRect(z*f,z*g,z,z),fillStyle="red",d||fillText(L,z*f+10,z*g+11)};s=function(){n[y][x]=3;2>n[y+1][x]?(n[++y][x]=1,k.push(y,x)):2>n[y-1][x]?(n[--y][x]=1,k.push(y,x)):2>n[y][x-1]?(n[y][--x]=1,k.push(y,x)):2>n[y][x+1]?(n[y][++x]=1,k.push(y,x)):(x=k.pop(),y=k.pop());n[y][x]=0;19==y&&19==x?e(h=z):o(s,50);for(r in n)for(l in n[r])i(n[r][l],l,r)};(e=function(){if(h--)q=z*(z-h),i(0,10,10),q=z,o(e,40);else{k=[];for(n=[],y=z;0<y--;){n[y]=[];for(x=z;0<x--;)n[y][x]=2}x=y=1;n[y][x]=0;for(k.push(y,x);k.length;)(p=L,18>y&&2==n[y+2][x]&&(p+=1),2<=y&&2==n[y-2][x]&&(p+=2),2<=x&&2==n[y][x-2]&&(p+=3),2==n[y][x+2]&&(p+=4),p!=L)?(1==(W=p[~~(Math.random()*p.length)])?n[++y][x]=n[++y][x]=1:2==W?n[--y][x]=n[--y][x]=1:3==W?n[y][--x]=n[y][--x]=1:4==W&&(n[y][++x]=n[y][++x]=1),k.push(y,x)):(x=k.pop(),y=k.pop());n[19][19]=0;s(y=x=1)}})()
// end of submission //
</script>
</body>
</html>
L="♥",q=z=h=21,b="#fff3#ffb3#4df3hsla(0,100%,84%,.1)".split(3),o=setTimeout;c.width=c.height=441;i=function(d,f,g){with(a)textAlign="center",textBaseline="middle",font=q+"px a",fillStyle=b[d],fillRect(z*f,z*g,z,z),fillStyle="red",d||fillText(L,z*f+10,z*g+11)};s=function(){n[y][x]=3;2>n[y+1][x]?(n[++y][x]=1,k.push(y,x)):2>n[y-1][x]?(n[--y][x]=1,k.push(y,x)):2>n[y][x-1]?(n[y][--x]=1,k.push(y,x)):2>n[y][x+1]?(n[y][++x]=1,k.push(y,x)):(x=k.pop(),y=k.pop());n[y][x]=0;19==y&&19==x?e(h=z):o(s,50);for(r in n)for(l in n[r])i(n[r][l],l,r)};(e=function(){if(h--)q=z*(z-h),i(0,10,10),q=z,o(e,40);else{k=[];for(n=[],y=z;0<y--;){n[y]=[];for(x=z;0<x--;)n[y][x]=2}x=y=1;n[y][x]=0;for(k.push(y,x);k.length;)(p=L,18>y&&2==n[y+2][x]&&(p+=1),2<=y&&2==n[y-2][x]&&(p+=2),2<=x&&2==n[y][x-2]&&(p+=3),2==n[y][x+2]&&(p+=4),p!=L)?(1==(W=p[~~(Math.random()*p.length)])?n[++y][x]=n[++y][x]=1:2==W?n[--y][x]=n[--y][x]=1:3==W?n[y][--x]=n[y][--x]=1:4==W&&(n[y][++x]=n[y][++x]=1),k.push(y,x)):(x=k.pop(),y=k.pop());n[19][19]=0;s(y=x=1)}})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment