1
\$\begingroup\$

The Demo for what I have made is located here: http://jsfiddle.net/maniator/H5LKy/181/

Basically I am trying to make a Wheel of Fortune type game.

Is there anything I could improve on in the code?

var WOF = (function() {

    Array.prototype.randomize = function() {
        this.sort(function(a, b) {
            return Math.round(Math.random());
        });
    };
    var prefix = (function() {
        if (document.body.style.MozTransform !== undefined) {
            return "MozTransform";
        }
        else if (document.body.style.WebkitTransform !== undefined) {
            return "WebkitTransform";
        }
        else if (document.body.style.OTransform !== undefined) {
            return "OTransform";
        }
        else {
            return "";
        }
    }()),
        degToRad = function(deg) {
            return deg / (Math.PI * 180);
        },
        rotateElement = function(element, degrees) {
            var val = "rotate(-" + degrees + "deg)";
            if (element.style[prefix] != undefined) element.style[prefix] = val;
            var rad = degToRad(degrees % 360),
                filter = "progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand', M11=" + rad + ", M12=-" + rad + ", M21=" + rad + ", M22=" + rad + ")";
            if (element.style["filter"] != undefined) element.style["filter"] = filter;
            element.setAttribute("data-rotation", degrees);
        },
        oc = function(a) { //object converter (changes array to an object)
            var o = {};
            for (var i = 0; i < a.length; i++) {
                o[a[i]] = '';
            }
            return o;
        },
        GAMECLASS = (function() {

            //static int
            var round = 0,
                //in the future this could be from an external server
                puzzles = [
                    "THE DARK KNIGHT RISES",
                    "TO BE OR NOT TO BE",
                    "PEANUT BUTTER JELLY TIME",
                    "WILLY WONKA AND THE CHOCOLATE FACTORY",
                    "SMASHMOUTH", "WHEEL OF FORTUNE",
                    "TIME IS RELATIVE"
                    ],
                vowels = ['A', 'E', 'I', 'O', 'U'],
                cards = ["200", "400", "-1", "750", "400", "150", "600", "400", "200", "1000", "800", "250", "500", "300", "250", "-2", "400", "200", "900", "500", "200", "0", "700", "450"],
                //br = 0, free spin = -1, lat = -2
                currentMoney = 0,
                spinWheel = document.getElementById('spin'),
                buyVowel = document.getElementById('vowel'),
                displayArea = document.getElementById('display'),
                wheel = document.getElementById('wheel'),
                newButton = document.getElementById('newpuzzle'),
                money = document.getElementById('money'),
                solve = document.getElementById('solve'),
                spinTimeout = false,
                spinModifier = function() {
                    return Math.random() * 10 + 20;
                },
                modifier = spinModifier(),
                slowdownSpeed = 0.5;

            return function GAME() {
                puzzles.randomize();

                var currentPuzzleArray = [],
                    lettersInPuzzle = [],
                    guessedArray = [],
                    puzzleSolved = false,
                    createBoard = function(currentPuzzle) {
                        guessedArray = [];
                        lettersInPuzzle = [];
                        lettersGuessed = 0;
                        puzzleSolved = false;
                        currentPuzzleArray = currentPuzzle.split("");
                        var word = document.createElement('div');
                        displayArea.appendChild(word);
                        word.className = "word";
                        for (var i = 0; i < currentPuzzleArray.length; ++i) {
                            var span = document.createElement('div');
                            span.className = "wordLetter ";

                            if (currentPuzzleArray[i] != " ") {
                                span.className += "letter";
                                if (!(currentPuzzleArray[i] in oc(lettersInPuzzle))) {
                                    lettersInPuzzle.push(currentPuzzleArray[i]);
                                }
                                word.appendChild(span);
                            }
                            else {
                                span.className += "space"
                                word = document.createElement('div');
                                displayArea.appendChild(word);
                                word.className = "word";
                                word.appendChild(span);
                                word = document.createElement('div');
                                displayArea.appendChild(word);
                                word.className = "word";
                            }

                            span.id = "letter" + i;
                        }

                        var clear = document.createElement('div');
                        displayArea.appendChild(clear);
                        clear.className = "clear";
                    },
                    solvePuzzle = function() {
                        if (!puzzleSolved && !createGuessPromt("SOLVE THE PUZZLE?", null, true)) {
                            alert("Puzzle NOT solved...");
                        }
                    },
                    guessLetter = function(guess, isVowel, solvingPuzzle) {
                        var timesFound = 0;
                        isVowel = isVowel == undefined ? false : true;
                        solvingPuzzle = solvingPuzzle == undefined ? false : true;
                        //find it:
                        if (guess.length && !puzzleSolved) {
                            if ((guess in oc(vowels)) && !isVowel && !solvingPuzzle) {
                                alert("Cannot guess a vowel right now!");
                                return false;
                            }
                            if (isVowel && !(guess in oc(vowels)) && !solvingPuzzle) {
                                alert("Cannot guess a consanant right now!");
                                return false;
                            }
                            for (var i = 0; i < currentPuzzleArray.length; ++i) {
                                if (guess == currentPuzzleArray[i]) {
                                    var span = document.getElementById("letter" + i);
                                    if (span.innerHTML != guess) {
                                        //found it
                                        ++timesFound;
                                    }
                                    span.innerHTML = guess;
                                    if (guess in oc(lettersInPuzzle) && !(guess in oc(guessedArray))) {
                                        guessedArray.push(guess);
                                    }
                                }
                            }

                            if (guessedArray.length == lettersInPuzzle.length) {
                                alert("PUZZLE SOLVED!");
                                puzzleSolved = true;
                            }

                            return timesFound;
                        }
                        return false;
                    },
                    nextRound = function() {
                        ++round;
                        if (round < puzzles.length) {
                            while (displayArea.hasChildNodes()) { //remove old puzzle
                                displayArea.removeChild(displayArea.firstChild);
                            }
                            createBoard(puzzles[round]);
                        }
                        else alert("No more puzzles!");
                    },
                    updateMoney = function() {
                        money.innerHTML = currentMoney;
                    },
                    spinWheelfn = function(amt) {
                        clearTimeout(spinTimeout);
                        if (!puzzleSolved) {
                            modifier -= slowdownSpeed;
                            if (amt == undefined) {
                                amt = parseInt(wheel.getAttribute('data-rotation'));
                            }
                            rotateElement(wheel, amt);
                            if (modifier > 0) {
                                spinTimeout = setTimeout(function() {
                                    spinWheelfn(amt + modifier);
                                }, 1000 / 5);
                            }
                            else {
                                modifier = spinModifier();
                                var card = cards[Math.floor(Math.round(parseInt(wheel.getAttribute('data-rotation')) % 360) / 15)];
                                switch (parseInt(card)) {
                                case 0:
                                    alert("BANKRUPT!");
                                    currentMoney = 0;
                                    break;
                                case -1:
                                    alert("FREE SPIN!");
                                    break;
                                case -2:
                                    alert("LOSE A TURN");
                                    break;
                                default:
                                    var timesFound = createGuessPromt("YOU SPUN A " + card + " PLEASE ENTER A LETTER");
                                    currentMoney += (parseInt(card) * timesFound);
                                }

                                updateMoney();
                            }
                        }
                    },
                    guessTimes = 0,
                    createGuessPromt = function(msg, isVowel, solvingPuzzle) {
                        solvingPuzzle = solvingPuzzle == undefined ? false : true;
                        if (!puzzleSolved) {
                            var letter = prompt(msg, "");
                            if (letter) {
                                var guess = '';
                                if (!solvingPuzzle) {
                                    guess = letter.toUpperCase().charAt(0)
                                }
                                else {
                                    guess = letter.toUpperCase().split("");

                                    function arrays_equal(a, b) {
                                        return !(a < b || b < a);
                                    };
                                    if (arrays_equal(guess, currentPuzzleArray)) {
                                        for (var i = 0; i < guess.length; ++i) {
                                            guessLetter(guess[i], isVowel, solvingPuzzle);
                                        }
                                    }
                                    return puzzleSolved;
                                }
                                var timesFound = guessLetter(guess, isVowel, solvingPuzzle);
                                if (timesFound === false) {
                                    ++guessTimes;
                                    if (guessTimes < 5) {
                                        return createGuessPromt(msg, isVowel, solvingPuzzle);
                                    }
                                }
                                guessTimes = 0;
                                return timesFound;
                            }
                            else {
                                ++guessTimes;
                                if (guessTimes < 5) {
                                    return createGuessPromt(msg, isVowel, solvingPuzzle);
                                }
                            }
                        }
                        return false;
                    };

                //CLICK EVENTS

                function bindEvent(el, eventName, eventHandler) {
                    if (el.addEventListener) {
                        el.addEventListener(eventName, eventHandler, false);
                    } else if (el.attachEvent) {
                        el.attachEvent('on' + eventName, eventHandler);
                    }
                }

                bindEvent(buyVowel, "click", function() {
                    if (currentMoney > 200) {
                        if (createGuessPromt("PLEASE ENTER A VOWEL", true) !== false) currentMoney -= 200;
                    }
                    else {
                        alert("You need more than $200 to buy a vowel");
                    }

                    updateMoney();
                });
                bindEvent(newButton, "click", nextRound);
                bindEvent(spinWheel, "click", function() {
                    spinWheelfn();
                });
                bindEvent(wheel, "click", function() {
                    spinWheelfn();
                });
                bindEvent(solve, "click", function() {
                    solvePuzzle();
                });

                this.start = function() {
                    createBoard(puzzles[round]);
                };
            }
        })(),
        game = new GAMECLASS;

    return game;

})();
WOF.start();​

I know that the wheel doesn't spin right in IE

\$\endgroup\$
1
\$\begingroup\$

Your array .randomize() isn't really that good. Consider:

var l = 100000, o = {}, a;

while( l-- ) {
    a = [1,2,3,4,5,6,7,8,9,10];
    a.randomize();
    if( !o[a[0]] ) {
        o[a[0]] = 0
    }

    o[a[0]]++;
}

Result:

Object
1: 29047
2: 28811
3: 19420
4: 10982
5: 5873
6: 2979
7: 1548
8: 745
9: 396
10: 199

See how often the number 1 ends up being in the first position? They should all end up in all positions 10000 (100000/10) times.

Now try:

var l = 100000, o = {}, a;

    while( l-- ) {
        a = [1,2,3,4,5,6,7,8,9,10];
        fisherYates( a );
        if( !o[a[0]] ) {
            o[a[0]] = 0
        }

        o[a[0]]++;
    }

Result:

Object
1: 9994
2: 10032
3: 10080
4: 10007
5: 9992
6: 10242
7: 9975
8: 9846
9: 9845
10: 9987

Implementation for fisherYates:

function fisherYates ( myArray ) {
  var i = myArray.length;
  if ( i == 0 ) return false;
  while ( --i ) {
     var j = Math.floor( Math.random() * ( i + 1 ) );
     var tempi = myArray[i];
     var tempj = myArray[j];
     myArray[i] = tempj;
     myArray[j] = tempi;
   }
}
\$\endgroup\$
  • 5
    \$\begingroup\$ var randomize = (function() { return 1; }()); would be better. \$\endgroup\$ – Florian Margaine May 31 '12 at 17:42
  • \$\begingroup\$ @FlorianMargaine oy... \$\endgroup\$ – Neal May 31 '12 at 17:56
  • \$\begingroup\$ @Esailija -- update: codereview.stackexchange.com/q/28973/3163 \$\endgroup\$ – Neal Jul 25 '13 at 14:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.