JS Canvas Timebane

Posted by aeron on Feb. 26, 2014, 2:07 p.m.

Spent a little time the past few days putting together this simple browser game using pure JS and the Canvas API. It was extremely easy to get started, I was up and drawing images to canvas within a couple minutes. The game logic itself was the only somewhat complicated part, but even so it isn't anything too dramatic. You've all probably played this game at some point in your lives:

After putting together the basic gameplay, I went ahead and tested it in the few browsers I had on hand. To my surprise, it worked fine out of the box until I tried zooming in. Turns out I used a property for mouse coordinates that didnt scale properly, so I had to run a search for the correct one. Then I got my first taste of browser inconsistencies, as some browsers called it layerX / layerY and others called it offsetX / offsetY. Luckily in JS this is a trivial problem to account for:

mouse.x = e.offsetX || e.layerX;

My original plan for this game was to try something different. I was gonna include all the built in levels pre-solved and have the game shuffle them into a new puzzle every time they're loaded. It seemed simple enough and at the very least worthy of experimentation. Well, I had finished the shuffle feature finally and just needed to add levels. I searched the net for packs of levels but I soon realized finding a significant amount pre-solved was out of the question. I did however happen upon a goldmine of levels (Im talking thousands) in a ripe format just waiting to be picked. So rather shamelessly, I converted them to my json format and they're now the default levels of my version. I decided to keep the initial shuffle enabled to add some spice and stay more in line with my initial idea, so there's still an element of surprise. I also decided to add a manual shuffle button which can be used to mix the board up if you're stuck in a rut. And don't worry, I made sure it never shuffled into a immediately winnable state :P

On top of the shuffle, I decided not to have a specified level order. There's no "next" level, you just click Random and it pulls up a fresh puzzle for ya. Which makes this a devilishly addicting timewaster since there's no telling which level of the thousands is waiting for you next. It also makes it easy to pick up anywhere without worrying about playing the same few levels over again.

Anyway, enough blabbering from me. Go ahead and give it a try:

Click here to play!

It should work no problem in any of the latest desktop browsers. Unfortunately I haven't got around to fixing it on mobile, as the touch API differs enough from the mouse API that I'll have to spend a good amount of time reworking and debugging it. Hopefully it's not as painful as I'm anticipating ;)

Finally, if I get the time I'll work on converting these levels to my format. Supposedly they're the most difficult configurations for this game, and I'd love to have an "insane mode" level pack ;)

Edit: Insane mode



F1ak3r 6 years, 4 months ago

Oh man, that kind of game is one of my many weaknesses. Had one on my phone a few years back – spent most of my Accounting lectures rearranging cars.

aeron 6 years, 4 months ago

How does your puzzle generation algorithm work?
I converted a pack of levels from the internet, so those are used as a base (there are over a thousand in the default set). I added a function that shuffles the level by picking a random car and moving it a random amount as per the game rules. It repeats this hundreds of times when the level is loaded, but also has a check to make sure it doesn't actually solve it for you (it runs again in that case).

So yeah, difficulty variation is in part due to the base levels being of varying difficulty, but also in part due to the shuffle setting you up for an easy win just by chance. You can technically abuse the shuffle button to work through most of the puzzle for you with enough presses and some luck, as it runs the shuffle algo a couple hundred times each click.

Acid 6 years, 4 months ago

I hate these games… but I see no flaws! Good job, aeron.

panzercretin 6 years, 4 months ago

now put mario graphics on it and accidentally get a jazillion downloads

aeron 6 years, 4 months ago

I hate these games… but
I think the only reason I survived high school was that I had games like this on my calculator to keep me from dying of boredom. In that respect, they still hold a special place in my heart :P

I challenge you to randomly generate levels on the fly, with varying difficulties.

My original plan was to do something along these lines, which is why I wanted to work backwards from a solved puzzle. I thought I could get away with starting from a nearly full board and deleting random cars according to difficulty, then shuffling several thousand times to get a random puzzle. But the more I thought about it I realized there was too much chance involved in that method (deleting cars dramatically changes the puzzle indeterminately), and the only legit way to gauge difficulty would be to actually write a solver and find the fastest solution. It might be worth visiting but I should say it's already been done in greater depth than I'd ever want to consider.

For instance, the link I posted in the blog with the hardest configurations. I found the guy's paper he wrote on how he came up with those results and it's indeed quite thorough, and totally scary. The thought of searching through 3.610 configurations for the longest solution is probably gonna give me nightmares for a few days.

But yeah, I'd like to come up with a relatively novel way of generating puzzles eventually. I know it'll take a solver to verify and categorize them, so I'll probably start with that.

Oh and about those hardest configurations, I went ahead and wrote a script to analyze the images and generate a level pack from them. You can play it here if you dare, it has all 532 puzzles from the web page. Might update the blog with info on how I did it if there's interest ;P