Slot machine in Javascript

Recently somebody talked to me about creating a slot machine. I looked on the web and could not find any good slot machine implementation in javascript. So I decided to write a quick one. My implementation uses jquery and a couple of jquery plugins for animation. Spritely is a wonderful jquery plugin for background animation. I also used a plugin for animating background-position since jquery does not support it natively.

Lets start building the slot machine. Demo here

First of all we need a sprite for our slot machine. This sprite is basically a reel which in motion simulates a slot. Its preferable to have blurred copy of this reel too, to show the effect of motion. For the purpose of this demo I got the sprite from internet.

The markup is very straightforward. We just need placeholders for 3 slots and a button as controller.

Lets got through the javascript now. First we need a class for a slot. Our 3 slots will be objects of this class.

function Slot(el, max, step) {
    this.speed = 0; //speed of the slot at any point of time
    this.step = step; //speed will increase at this rate
    this.si = null; //holds setInterval object for the given slot
    this.el = el; //dom element of the slot
    this.maxSpeed = max; //max speed this slot can have
}

Why do we need so many paramaters for a slot machine? That’s because each slot of an ideal slot machine should have different acceleration and speed. Also its good to have different max speeds.
Our Slot class will have 4 member functions:

  • start() – starts a slot
  • stop() – stops a slot
  • finalPos() – finds the final position of the slot when its stopped
  • reset() – Resets a slot for another run

How it works?

Initially we create an object for each slot of the slot machine. We pass different values for the max-speed and speed-stepper to the constructor.

var a = new Slot('#slot1', 30, 1),
    b = new Slot('#slot2', 45, 2),
    c = new Slot('#slot3', 70, 3);

When a user presses ‘Start’, start method is called for each slot. This method kicks off the slot and increments the speed at regular intervals. This can be done using setInterval. Code below:

Slot.prototype.start = function() {
    var _this = this;
    $(_this.el).addClass('motion');
    $(_this.el).spStart();
    _this.si = window.setInterval(function() {
        if(_this.speed < _this.maxSpeed) {
            _this.speed += _this.step;
            $(_this.el).spSpeed(_this.speed);
        }
    }, 100);
};

Once all the slots reach their maximum speeds, the ‘Stop’ button is enabled. When the user presses ‘Stop’, the speed of the slots start decrementing.

Slot.prototype.stop = function() {
    var _this = this,
        limit = 30;
    clearInterval(_this.si);
    _this.si = window.setInterval(function() {
        if(_this.speed > limit) {
            _this.speed -= _this.step;
            $(_this.el).spSpeed(_this.speed);
        }
        if(_this.speed <= limit) {
            _this.finalPos(_this.el);
            $(_this.el).spSpeed(0);
            $(_this.el).spStop();
            clearInterval(_this.si);
            $(_this.el).removeClass('motion');
            _this.speed = 0;
        }
    }, 100);
};

Once the speed comes below a certain threshold, the final position is calculated for each of the slots based on their current position and the slots are rotated to reach the final position.

Slot.prototype.finalPos = function() {
    var el = this.el,
        pos,
        posMin = 2000000000,
        best,
        bgPos,
        i,
        j,
        k;
 
    el_id = $(el).attr('id');
    pos = document.getElementById(el_id).style.backgroundPosition;
    pos = pos.split(' ')[1];
    pos = parseInt(pos, 10);
 
    for(i = 0; i < posArr.length; i++) {
        for(j = 0;;j++) {
            k = posArr[i] + (imgHeight * j);
            if(k > pos) {
                if((k - pos) < posMin) {
                    posMin = k - pos;
                    best = k;
                }
                break;
            }
        }
    }
 
    best += imgHeight + 4;
    bgPos = "0 " + best + "px";
    $(el).animate({
        backgroundPosition:"(" + bgPos + ")"
    }, {
        duration: 200
    });
};

Demo
You can see the implementation here.
The full source code can be viewed at my GitHub repository

Last Breath

I wish for things, never to own.
I wait for friends, already gone.
I try to see, things unseen.
I wander places, never been.
I hide the wound, and bear the pain.
I ask myself, will it rain.
I ask you, nothing you say.
I see the light, but far away.
I close my eyes, and find peace.
I say goodbye, forever to sleep.

Create simple tooltips with CSS and jQuery

A very nice article was posted by Kriesi, a Vienna based web designer, on creating simple tooltips using CSS and jQuery. It’s a great tutorial specially for beginners. Go ahead and read it at Kriesi’s Blog.

Trie implementation in Javascript

A trie, or prefix tree, is a multi-way tree structure useful for storing strings over an alphabet. It is very efficient and handy and can be used for various purposes like auto-complete, spell-check, dictionary search, etc.

The basic idea of a Trie goes as below:

  • We have a root node which represents an empty string.
  • Every other node either represents a word or a prefix of one or more words.
  • Each node can have atmost as many children as the size of the alphabet.

Trie example

The above diagram shows a trie which stores the words “A”, “to”, “tea”, “ted”, “ten”, “i”, “in”, and “inn”.

Below is my implementation of Trie in javascript:

At each node of Trie, I store the word-count, prefix-count and the link to children.

Trie = function() {
    this.words = 0;
    this.prefixes = 0;
    this.children = [];
};

To insert a word, I recursively traverse through the trie nodes if they already exist, else I create new nodes. While traversing the nodes, I keep on storing the information in the nodes as I encounter each character in the given string.

insert: function(str, pos) {
    if(str.length == 0) { //blank string cannot be inserted
        return;
    }
    var T = this,
        k,
        child;
    if(pos === undefined) {
        pos = 0;
    }
    if(pos === str.length) {
        T.words ++;
        return;
    }
    T.prefixes ++;
    k = str[pos];
    if(T.children[k] === undefined) { //if node for this char doesn't exist, create one
        T.children[k] = new Trie();
    }
    child = T.children[k];
    child.insert(str, pos + 1);
}

Removing a word follows the similar idea as insertion.

To update, I simply remove the existing word and insert the new word.

Searching a word is trivial as we just need to check if the word count at the terminating node of the input string is greater than zero or not.

find: function(str) {
    if(str.length == 0) {
        return false;
    }
    if(this.countWord(str) > 0) {
        return true;
    } else {
        return false;
    }
}

You can get the full source code in my GitHub repository

Meanwhile you can see the auto-complete demo using my trie implementation

Links:

Snake in Javascript

This weekend I spent a few hours to write the classic game of Snake in javascript. There are already many versions of Snake available on the web. This was just some fun way to practice javascript. I used YUI 2 for event and dom handling. I have already written a few games in other languages like C++ and Basic during school/college days but this is my first game in Javascript. Will try to write better games in the future probably using HTML5 which can give a much better experience.

The game can be played at http://odhyan.com/snake/

The javascript code can be viewed at http://odhyan.com/snake/snake.js

Caching in Javascript (YUI Cache)

Today I read about YUI 3 Caching Utility. It allows to cache frequently used data in javascript memory (Basic caching) or HTML5 localStorage object (Offline caching). Although we can implement our own caching mechanism in javascript, the YUI caching is general purpose and also provides a set of events. Moreover it can be easily integrated with YUI Datasource which can be very beneficial.

I’ll show you how useful YUI caching utility can be using a very standard example, Factorial. Here I’ll only cover basic caching.

Let’s write a factorial program in javascript without any caching/memoization:

YUI().use('node', function() {
    // method to calculate factorial
    var factorial = function(n) {
        if(n === 0 || n === 1) {
            return 1;
        } else {
            return n * factorial(n-1);
        }
    }
    // calulate the factorials and display the values on browser
    var MAX = 100,
        ret = "",
        el,
        i;
    for(i = 1; i < MAX; i++) {
        ret += i + "! = " + factorial(i) + "</br>";
    }
    el = document.getElementById("fact"); // create this div in HTML code
    el.innerHTML = ret;
});

Try increasing the value of MAX and you’ll see that your browser may get very slow/crash. My firefox keeps on running the script and then shows a dialog box to stop the script. I assume all must be familiar with factorial and should be able to understand why this program is highly inefficient.

Now lets write another factorial program using our own caching mechanism:

YUI().use('node', function() {
    // create a cache class
    var MyCache = function() {
        this.memo = [];
    };
    MyCache.prototype.add = function(key, val) {
        this.memo[key] = val;
    };
    MyCache.prototype.retrieve = function(key) {
        return this.memo[key];
    };
    // a new cache object
    var cache = new MyCache();
    // method to calculate factorial
    var factorial = function(n) {
        var ret;
        if(n === 0 || n === 1) {
            return 1;
        } 
        ret = cache.retrieve(n);
        if(ret !== undefined) {
            return ret;
        } else {
            ret = n * factorial(n-1);
            cache.add(n, ret);
            return ret;
        }
    };
    // calulate the factorials and display the values on browser
    var MAX = 100,
        ret = "",
        el,
        i;
    for(i = 1; i < MAX; i++) {
        ret += i + "! = " + factorial(i) + "</br>";
    }
    el = document.getElementById("fact"); // create this div in HTML code
    el.innerHTML = ret;
});

The above code runs smoothly even if we increase the value of MAX(even 5000 should be fine although 5000! doesn’t make sense). That’s because we cache the value of every factorial we calculate and then reuse it for the next calculation.

Now lets write the same program using YUI caching utility:

YUI().use('cache', function(Y) {
    // create a yui cache object
    var cache = new Y.Cache({
        max:100
    });
    // method to calculate factorial
    var factorial = function(n) {
        var ret;
        if(n === 0 || n === 1) {
            return 1;
        }
        ret = cache.retrieve(n);
        if(ret !== null) {
            return ret.response;
        } else {
            ret = n * factorial(n-1);
            cache.add(n, ret);
            return ret;
        }
    }
    // calulate the factorials and display the values on browser
    var MAX = 100,
        ret = "",
        el,
        i;
    for(i = 1; i < MAX; i++) {
        ret += i + "! = " + factorial(i) + "</br>";
    }
    el = document.getElementById("fact"); // create this div in HTML code
    el.innerHTML = ret;
});

This also runs smoothly for large values of MAX.

For this particular example, implementation 2 (using our own caching) will be slightly more efficient than the YUI version due to the simplicity, but in more complex examples, YUI caching utility can be quite useful.

You can read more about the YUI Cache here.

Related links:

YQL – Yahoo! Query Language

Recently I have been reading about YQL. YQL is a great idea that came out of Yahoo! and is an awesome tool for developers. Basically YQL allows you to fetch information from the web using SQL like syntax. Yahoo! provides a good number of open data tables and many more are contributed by the open source community. Check out the community page at http://datatables.org.

I was just playing around with the stuff and built a small example application as a YQL demo. This app fetches movie information from IMDB. I used the open data table created by CerealBoy. The way it works is it scrapes the HTML from IMDB and extracts the needed information. In this example, YQL acts as a proxy and easily solves the cross-domain AJAX problem.

Checkout the demo here: http://odhyan.com/yql/movies/

Links:

ACK – Better than GREP

One of the most useful tools in unix is grep. Almost every unix/linux user use it frequently. But not many know about a tool which is better then grep – ack. It makes life so easy for you. Some of the features that made me switch to ack:

  • Lot faster than grep.
  • Default recursive search.
  • Ignores most of the crap you don’t want to search: SVN, CVS, binary files, etc.

So instead of doing

grep -r ‘string’ . | grep -v ‘\.svn’ | grep -v ‘FreeBSD’

I can do

ack ‘string’

  • By default searches only the files that it recognizes. You can edit the list of files so that ack can recognize them or use a flag to search all files.
  • Color highlighting of search results.

Since ack is written in perl, it has ports for both mac and windows.

So if you haven’t used ack yet, give it a try. Trust me, you’ll love it.

Useful applications for MacOS X

Some of the useful applications/utilities I use on my Macbook Pro:

  • Textmate
  • Notepad++ used to be my favorite code editor an year ago when I was a Windows user. I still feel Notepad++ is the best GUI based text editor, very useful and lightweight. But Textmate is equally good and when you get used to it, you’ll realize the power it offers to you.
  • Adium
  • Probably the best messenger client on Mac. Supports all the major IM services.
  • DiffMerge
  • A simple but useful diff utility for Mac. Allows to merge content. Editing is possible while viewing the diff.
  • Disk Inventory X
  • Visual representation of all files on your Mac. Files are represented as blocks. Block size represents the size of the file. Very handy when you need to clear up some disk space.
  • iTerm
  • Perhaps a better terminal application than the one bundled with Mac.
  • JustLooking
  • Very useful and lightweight image viewer. This is a must as the default image viewing utility in Mac, Preview, is short of a lot of features.
  • Breakaway
  • A pretty useful application that pauses the music in iTunes when you hit the mute button or pull out your headphones.
  • Clyppan
  • Clipboard history application for Mac that keeps a list of text you have copied to the clipboard and allows you to paste it again by selecting it from the list within Clyppan.
  • EverNote
  • Just started using but seems to be a nice tool for keeping notes. A good alternative for OneNote on Windows.
  • Miro
  • The best internet video application. Watch or download online videos including YouTube. Nice interface.
  • CyberDuck
  • CyberDuck is a nice and simple FTP utility. You can edit text files remotely without downloading. Also supports drag and drop.
  • Firefox/Chrome
  • My favorite browsers on both Mac and Windows. Generally I use Firefox for development purpose due to the large set of development tools available for it.
  • iTunes
  • Probably the best music player for Mac.
  • Folx
  • A nice download utility for Mac.
  • Parallels
  • Parallel Desktop allows you to run any other OS in a virtual machine. I use it to run windows as web developers can’t live without windows :P The other best alternative to Parallels is VMware Fusion.
  • Stickies
  • When you need to take quick short notes on yellow paper :)
  • Entourage
  • My email client. Thunderbird is a free(maybe better) alternative but since I started with Entourage, was too lazy to shift :P
  • VLC
  • The best video player on any platform.
  • Photoshop
  • No need to say that Photoshop is the best image editing tool available. Only problem: It’s not free.

YUI Lightbox

While working on my last project (Floating Cart for Yahoo! stores) at Yahoo!, I came across an application called Lightbox. The reason it drew my attention was incompatibility with our application. Our customers who had lightbox were facing issues using the Floating Cart. The problem was not with the lightbox application, but the javascript framework called Prototype that was used to create the application. I’ll post the details about this in some other post, let’s move to lightbox for now.

So you must be wondering what lightbox is? It’s a simple but useful application to overlay images on the current page. Simply speaking, if you are on a webpage with multiple image thumbnails which link to the actual images, using lightbox the images will open up on the same page in a modal window. To add this feature, you just need to add the lightbox script (and all dependencies) to your website. There are multiple versions of lightbox available on the internet but this one is the most popular. It uses Prototype javascript Framework and Scriptaculous Effects Library.

This weekend I spent a few hours trying to create my own version of lightbox using YUI 2. Its a very basic implementation and uses the Panel widget from YUI. I also added a few effects to it. Since ContainerEffect contains only SLIDING and FADING effects, I added a few of mine.

The demo can be viewed here: YUI Lightbox Demo

Installation

The lightbox script can be downloaded from here: lightbox.js lightbox.css

To make lightbox work, you need to add the following YUI javascript and CSS files to your page:

<script src="http://yui.yahooapis.com/2.8.0r4/build/yahoo-dom-event/yahoo-dom-event.js" type="text/javascript"></script>
<script src="http://yui.yahooapis.com/2.8.0r4/build/container/container.js" type="text/javascript"></script>
<script src="http://yui.yahooapis.com/2.8.0r4/build/animation/animation-min.js" type="text/javascript"></script>

Initialize

Use the following code within script tags in your HTML page to initialize lightbox:

function initLightbox() {
    var lightbox = new YAHOO.odhyan.Lightbox;
    lightbox.init();
}
YAHOO.util.Event.on(window, 'load', initLightbox);

HTML to use

Its very easy to add lightbox to any of your links. Just add a classname of yui-lightbox to your anchor element.

<img src="img/image1_thumb.jpg" alt="" />

For better understanding, view the code of index.html

You can customize the lightbox style by adding your own styles to lightbox.css

This is not the first lightbox implementation using YUI. There already exists one and can be viewed here.

Links

Copyright © Saurabh Odhyan's Blog

Built on Notes Blog Core
Powered by WordPress