Ultra Puzzle

I find multi touch functionality of ultrabook really interesting to me so i decided to develop this puzzle over window 8 platform of ultrabook which uses multi touch functionality of ultrabook effectively.

Ultra Puzzle is a puzzle game created using visual studio 12 for windows 8.This can be played while doing some other task also.So anyone can play this puzzle game along with some other work also.There are many other functionality i can think of to implement in this puzzle game and now working on them. It will be really easy to use this application game. All i need is to test this game over window 8 ultrabook and adding much more new functionality to make it more interesting and addictive.

Ultra Puzzle is basically a solitaire matching game. Match tile pairs until all of the tiles are gone. To be selectable, a tile must have a side edge free and must have no other tiles on top of it. If there is no moves left, you can use your super power once. You can choose any pairs of tiles in power mode.

Background

Solitaire has always been an addictive game for me. I am playing it when i was 8 years old. Well while playing solitaire last month. I got this idea to make a puzzle which uses cards and after working on Visual studio 12 for windows 8 i got some success. I have attached a working prototype of this game. I have tested this on simulator and this worked fine. All i need is to test this puzzle game over real window 8 ultrabook and adding various other functionality that i can think of. It would also be nice if i can get feedback over this puzzle game over prototype that will be really helpful in future development of this application.

A windows 8 project of the app is attached with the article so that it can be tested on various devices. The app is made using windows 8 HTML5 SDK. To run the app you must have windows 8 RTM running on your machine with latest version of Visual Studio 12. The app uses CSS3.0 transforms and animation to implement gameplay. A custom version of Jquery is used as utility .

Using the code

I have attached complete code of working prototype with this article. You can view the entire code attached. Here i am showing some basic code snippet that how it works.I have been working on implementing the methods for using the advanced features of the new ultrabooks to make tha app best in the store. There are lot of more features that i am trying to embed in it. and they will be coming soon as i get to test this puzzle game over ultrabook.

Collapse | Copy Code var classes = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']; var bR, bS, tM, oT, tI, hS; var counts = [], bM = [], pP = []; var pA = false, mP = 1;

$(document).ready(function() { setScale(); $(window).resize(setScale); if (!('ontouchstart' in document)) { $('body').addClass('pc'); } $('#s1').click(function() { $('#s1').hide(); gameStart(); $('#s2').show(); }); });

function gameStart() { setBlocks(); tM = $('#a1 div.tm'); hS = $('#a1 div.hs'); oT = new Date(); tI = setInterval("setTimer()", 1000); setHs(); $('.ht').click(hint); $('.b3').click(reset); }

function setScale() { var wtt = $(window).width(); var htt = $(window).height(); var sl = Math.min(wtt, htt); if(sl < 500) { var bodyScale = (sl * .357); if(wtt > htt) $('body').addClass('ld'); else $('body').removeClass('ld'); } else if(wtt > (htt * .6)){ var bodyScale = (htt * .18); $('body').removeClass('ld'); } else { var bodyScale = (wtt * .3); $('body').removeClass('ld'); } $('body').css('font-size', bodyScale + '%'); }

function setBlocks() { bR = 0; counts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] var mR = 5, mC = 6; var tempFloor, tempRow, tempBlock; var floors = $('ul'); floors.empty(); for (var f = 0; f < 4; f++) { bM[f] = []; for (var r = 0; r < mR; r++) { bM[f][r] = []; tempRow = $('

  • '); $(floors[f]).append(tempRow); for (var c = 0; c < mC; c++) { var randomNoRequired = true; var randomClass; while(randomNoRequired) { randomClass = Math.round(Math.random() * 10 + 0); if (counts[randomClass] < 6 || bR >= 66) { randomNoRequired = false; } } if (bR > 65) { tempBlock = $(''); bM[f][r][c] = {idx:null,type:null,v:0,e:null}; } else { tempBlock = $(''); bM[f][r][c] = {idx:bR,type:classes[randomClass],v:1,e:tempBlock}; counts[randomClass]++; bR++; } tempBlock.css('margin-top', ((-(mR * 3.05 / 2) + (3.05 * r)) - .15) + 'em'); tempBlock.css('margin-left', (-(mC * 2.3 / 2) + (2.3 * c)) + 'em'); tempRow.append(tempBlock); } } mR--; mC--; } if (!checkAllBlocks()) { setBlocks(); } else { $('#s2 a').click(function(){ var cB = $(this); var f = parseInt(cB.attr('data-f')); var r = parseInt(cB.attr('data-r')); var c = parseInt(cB.attr('data-c')); if (pA == false && !isClickAllowed(f,r,c)) { return false; } cB.addClass('ss'); if (bS) { if ($(bS).attr('data-i') == cB.attr('data-i')) { cB.removeClass('ss'); } else { if ($(bS).attr('data-t') == cB.attr('data-t')) { $(bS).addClass('x'); cB.addClass('x'); bR = bR - 2; turnoffMatrix($(bS)); turnoffMatrix(cB); $('body').removeClass('pw'); pA = false; } else { $(bS).removeClass('ss'); cB.removeClass('ss'); } } bS = null; } else { bS = this; }

            if (bR == 0) {
                clearInterval(tI);
                enddingProcess();
                //$('#s2').hide();
                $('#s3').show();
            } else {
                if (checkAllBlocks() == false && pA == false) {
                    if (mP > 0) {
                        $('#ms').html('<h2>No More Moves Left</h2>You only have one chance to use super power.<br>Choose a pair of blocks wisely.<br><div id="b1">Power</div>');
                        $('#mw').show();
                        $('#b1').click(power);
                    } else {
                        clearInterval(tI);
                        $('#ms').html('<h2>No More Moves Left</h2>Game Over. Try again.<br><div class="b3">RESTART</div>');
                        $('#mw').show();
                        $('#ms div.b3').click(reset);
                    }               
                }
            }
        });
    }
    

    }

    function isClickAllowed(f, r, c) { var fR = false, cR = false;

    if (f == 3) {
        fR = true;
    } else {
        if (typeof bM[f+1][r-1] == 'undefined') {
            if (typeof bM[f+1][r][c-1] == 'undefined') {
                if (bM[f+1][r][c].v == 0) {
                    fR = true;  
                }
            } else if (bM[f+1][r][c-1].v == 0) {
                if (typeof bM[f+1][r][c] == 'undefined') {
                    fR = true;
                } else if (bM[f+1][r][c].v == 0) {
                    fR = true;
                }
            }
        } else if (typeof bM[f+1][r] == 'undefined') {
            if (typeof bM[f+1][r-1][c-1] == 'undefined') {
                if (bM[f+1][r-1][c].v == 0) {
                    fR = true;
                }
            } else if (bM[f+1][r-1][c-1].v == 0) {
                if (typeof bM[f+1][r-1][c] == 'undefined') {
                    fR = true;
                } else if ( bM[f+1][r-1][c].v == 0) {
                    fR = true;
                }
            }
        } else {
            if (typeof bM[f+1][r-1][c-1] == 'undefined' && typeof bM[f+1][r][c-1] == 'undefined') {
                if (bM[f+1][r-1][c].v == 0 && bM[f+1][r][c].v == 0) {
                    fR = true;
                }
            } else if (typeof bM[f+1][r-1][c] == 'undefined' && typeof bM[f+1][r][c] == 'undefined') {
                if (bM[f+1][r-1][c-1].v == 0 && bM[f+1][r][c-1].v == 0) {
                    fR = true;
                }
            } else {
                if (bM[f+1][r-1][c-1].v == 0 && bM[f+1][r][c-1].v == 0 && bM[f+1][r-1][c].v == 0 && bM[f+1][r][c].v == 0) {
                    fR = true;
                }
            }
        }
    }
    if (c == 0) {
        cR = true;
    }
    if (typeof bM[f][r][c-1] == 'undefined') {
        cR = true;
    } else if (bM[f][r][c-1].v == 0) {
        cR = true;
    }
    if (typeof bM[f][r][c+1] == 'undefined') {
        cR = true;
    } else if (bM[f][r][c+1].v == 0) {
        cR = true;
    }
    return (fR && cR);
    

    }

    function turnoffMatrix(el) { var f = parseInt(el.attr('data-f')); var r = parseInt(el.attr('data-r')); var c = parseInt(el.attr('data-c')); bM[f][r][c].v = 0; }

    function checkAllBlocks(sB) { var mR = 5, mC = 6; var checkResult; for (var f = 0; f < 4; f++) { for (var r = 0; r < mR; r++) { for (var c = 0; c < mC; c++) { if(!sB) { if (bM[f][r][c].v == 1 && isClickAllowed(f,r,c)) { checkResult = checkAllBlocks(bM[f][r][c]); if (checkResult) { return true; } } } else { if (sB.idx != bM[f][r][c].idx) { if (sB.type == bM[f][r][c].type) { if (bM[f][r][c].v == 1 && isClickAllowed(f,r,c)) { pP = [sB, bM[f][r][c]]; return true; } } }

                }
            }
        }
        mR--;
        mC--;
    }
    pP = [];
    return false;
    

    }

    function setTimer() { var n = new Date(); tM.text(getTimeText(n.getTime() - oT.getTime())); }

    function setHs() { if (typeof localStorage.highscore == 'undefined') { //hS.text('Try the first Record!'); } else { hS.text(getTimeText(parseInt(localStorage.highscore))); } } function getTimeText(v) { var vH = Math.floor(v / 3600000); var vM = Math.floor((v - (vH * 3600000)) / 60000); var vS = Math.floor((v - (vH * 3600000) - (vM * 60000)) / 1000); return set2Digit(vH) + ':' + set2Digit(vM) + ':' + set2Digit(vS); }

    function set2Digit(ov) { var os = '0' + ov; return os.substr(os.length - 2, 2); }

    function enddingProcess() { var n = new Date(); var tG = n.getTime() - oT.getTime(); var oHs = (typeof localStorage.highscore == 'undefined') ? 0 : parseInt(localStorage.highscore); var mHs = (oHs == 0) ? tG : Math.min(tG, oHs); localStorage.setItem('highscore', mHs); }

    function power() { if (mP > 0) { pA = true; mP--; $('#mw').hide(); $('body').addClass('pw'); } else { alert('no more power'); } }

    function pickATopBlock(oB) { var mR = 2, mC = 3; for (var f = 3; f >= 0; f--) { for (var r = 0; r < mR; r++) { for (var c = 0; c < mC; c++) { if (oB) { if (bM[f][r][c].v == 1 && bM[f][r][c].type == oB.type && bM[f][r][c].idx != oB.idx) { return bM[f][r][c]; } } else { if (bM[f][r][c].v == 1) { return bM[f][r][c]; } } } } mR++; mC++; } }

    function reset() { $('#s3').hide(); $('#s2').show(); setBlocks(); clearInterval(tI); oT = new Date(); tI = setInterval("setTimer()", 1000); $('#mw').hide(); $('.ht').show(); setHs(); mP = 1; bS = null; }

    function hint() { if (pA == true) { alert('Now\'s the power mode. Select a pair of blocks.'); return false; } $(this).hide(500); checkAllBlocks(); var tf = function() { $(this).removeClass('htb'); }; if ($.browser.webkit) { pP[0].e.bind('webkitAnimationEnd', tf); pP[1].e.bind('webkitAnimationEnd', tf); } else { pP[0].e.bind('animationend', tf); pP[1].e.bind('animationend', tf); } pP[0].e.addClass('htb'); pP[1].e.addClass('htb'); } You can download the entire code attached. Presently I am working to make app more touch responsive and trying to make UX better.

    Points of Interest

    Well it is always fun to code things that you can imagine. It is really nice to see many awesome features in new ultrabook. and really want to implement those in my windows 8 ultrabook applications.

    Your comments and suggestions are precious to me so please help me in improving this app.Suggestions on adding any new features will be highly appreciated.

    I will keep updated regarding new milestones in this puzzle game.

    Comments

    vignesh4303 Nov 5 '12 at 8:14
    nice application mate,and i guess providing code prototype with application's description is unnecessary ,as per contest rules please update your application's logo,screenshots!excited about this application post download link soon