Category Programming

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

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:

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