Javascript: Code Review - Need help deciding what to put in an Object

Started by
1 comment, last by Geejayz 8 years, 7 months ago

Hi all,

I decided to start my game development efforts by making a 'Deal or No Deal' style game.

So far I have it create 8 boxes in the browser window, the player chooses one to keep, then picks boxes one by one until they either deal or there are two boxes left.

I initially set up the program using arrays only but then started to learn more about objects. I have created a boxObject but feel there could perhaps be room for adding more of my program into the object that creates the boxes to reduce repetition - I am stuck however and would welcome some advice.

The code for the main script is below (I haven't included the html or css code).




// Set Up All Required Game Variables and initialise Game Requirements

var SIZE = 50;

var SPACE = 10;

var selectedBox;

var selectedBoxId;

var playerBox = [];

var boxNo =[];

var totalCash =0;

var cashLeftInGame = 0;

var lowestValue;

var highestValue;

var moneyLeft = [];

var bankerOffer;



        

var money = [50, 100, 250, 500, 1000, 3000, 5000, 10000];

    

// Randomise placement of money inside boxes

shuffle(money);

        





var boxArray = [];



var boxObject = {

    boxID : undefined,

    boxNo : undefined,

    boxValue : undefined,

    open : false

};



//Create a boxObject for each value that the money array contains



for (var i=0; i < money.length; i++) {

    boxArray[i] = Object.create(boxObject); //create one box for each array index

    boxArray[i].boxValue = money[i]; //set the value of each box to the value from the money array

    boxArray[i].boxID = parseInt(i+1); //give each box an ID from 1 to number of boxes

    console.log(boxArray[i].boxID + ':' + boxArray[i].boxValue);

}





var round = 0;

var roundLimit = boxArray.length-1;

console.log(boxArray);





displayBoard();

addClickHandlers();

output.innerHTML = "Welcome to Deal or No Deal";

output.innerHTML +="<br/> Please choose your box to bring to the table";





function displayBoard() {

    //Clear the stage of any previous elements

    stage.innerHTML = "";

    

    for (var i=0; i < boxArray.length; i++) {

        

        //create a div html element called boxImage

        var boxImage = document.createElement("div");

                    

        //set its CSS class to "cell"

        boxImage.setAttribute("class","cell");

        

        //give it an ID of boxID from 1 to boxes.length

        console.log(boxArray[i].boxID);

        boxImage.setAttribute("id", "boxNo" + (boxArray[i].boxID));

            

        //add the div element to the stage

        stage.appendChild(boxImage);

        

        //add box number inside the image

        boxImage.innerHTML = boxArray[i].boxID;

        

        if (boxArray[i].open === true) {

            boxImage.style.backgroundColor = "grey";

            boxImage.style.cursor = "default";

        }

            

        boxImage.style.left = parseInt(boxArray[i].boxID) * (boxArray[i].SIZE + SPACE) + "px";

        boxImage.style.top = "50px";

    }

    

}



function addClickHandlers() {

    for (var i=0; i < boxArray.length; i++) {

        //Add eventListeners to each unopened box to determine which is clicked

        

        if (boxArray[i].open === false) {

        boxNo[i] = document.getElementById('boxNo' + (boxArray[i].boxID));

        boxNo[i].addEventListener("click", clickHandler);

        boxNo[i].index = i; // create a parameter to link the index to each box

        }

    }

}



function removeHandlers() {

    for (var i=0; i < boxArray.length; i++) {

        boxNo[i] = document.getElementById('boxNo' + (boxArray[i].boxID));

        boxNo[i].removeEventListener("click", clickHandler);

    }

}



function clickHandler(event){

    selectedBox = parseInt(event.target.innerHTML);

    selectedBoxId = event.target.id;

    selectedBoxIndex = event.target.index;

    console.log('Box No Clicked: ' + selectedBox);

    console.log('Index: ' + selectedBoxIndex);

    removeHandlers();

    validateInput();

}



function validateInput() {

    playGame();

}



function playGame() {

    output.innerHTML = "";

    if (round === 0) {

        //Set playerBox to the value of the selected box

        playerBox = boxArray[selectedBoxIndex];

            

        //Remove the selected box from the array;

        boxArray.splice(selectedBoxIndex,1);

    

        //Redraw the board

        displayBoard();

    

        //Add the playerBox to the table area

        //create a div html element called boxImage

        var boxImage = document.createElement("div");

                    

        //set its CSS class to "cell"

        boxImage.setAttribute("class","cell");

        boxImage.setAttribute("id","boxNo" + (playerBox.boxID));

            

        //add the div element to the stage

        table.appendChild(boxImage);

        boxImage.style.position = "static";

        boxImage.style.margin = "40px auto";

        

        //add box number inside the image

        boxImage.innerHTML = playerBox.boxID;

    

        console.log(playerBox);    

        

        output.innerHTML = "You have chosen box number " + selectedBox;

        output.innerHTML += "<br/>We're ready to go. Please choose your first box to open.";

        addClickHandlers();

    }

    

    else {

        output.innerHTML = "Your selected box contains $" + boxArray[selectedBoxIndex].boxValue;

        boxArray[selectedBoxIndex].open = true;

        makeOffer();

        playerDecision();

    }

    

    round = round + 1;

    console.log('Round: '+round);



}



function makeOffer() {

    //reset values

    totalCash=0;

    cashLeftInGame=0;

    moneyLeft = [];

    

    for (i=0; i < money.length; i++) {

        totalCash += money[i];

    }

    for (i=0; i < boxArray.length; i++) {

        if (boxArray[i].open === false) {

            cashLeftInGame += boxArray[i].boxValue;

            moneyLeft.push(boxArray[i].boxValue);

        }

    }

    cashLeftInGame += playerBox.boxValue; //Add in the cash in playerBox that no-one has seen yet.

    

    lowestValue = getMin(moneyLeft);

    highestValue = getMax(moneyLeft);

    averageValue = (cashLeftInGame / moneyLeft.length);

    

    bankerOffer = ((cashLeftInGame/2/moneyLeft.length)*0.55).toFixed(2);

    console.log('Boxes Left:' + moneyLeft.length);

    

    output.innerHTML += ". <br/> The banker offers you $" + bankerOffer;

}



function playerDecision(){

    removeHandlers();

    displayBoard();

    controls.style.display = "block";

    deal.onclick = function(){endGame('deal');};

    noDeal.onclick = function(){nextRound();};

}



function nextRound() {

    if(round === roundLimit) {

        console.log('LastRound');

        controls.style.display = "none";

        output.innerHTML = "That was the last round and you have ";

        output.innerHTML +="<br/> decided to keep your box";

        output.innerHTML +="<br/> Let's see what it contained...";

        setTimeout(function(){ endGame('keepBox'); }, 5000);

    }

    else {

        controls.style.display = "none";

        output.innerHTML = "OK, let's play on. Welcome to Round " + round;

        output.innerHTML +="<br/> Please choose your next box to open";

        addClickHandlers();

    }

}



function endGame(choice){

    controls.style.display = "none";

    output.innerHTML = "Your box contained $" + playerBox.boxValue;

    output.innerHTML += "<br/> The banker's offer was $" + bankerOffer;

    

    if ((playerBox.boxValue < bankerOffer) && (choice === 'deal')) {

        output.innerHTML += "<br/> Congratulations, you beat the banker.";

    }

    else if ((playerBox.boxValue < bankerOffer) && (choice === 'keepBox')) {

        output.innerHTML += "<br/> You could have walked away with more money.";

    }

    else if ((playerBox.boxValue > bankerOffer) && (choice === 'keepBox')) {

        output.innerHTML += "<br/> Congratulations, you beat the banker.";

    }

    else {

        output.innerHTML += "<br/> You could have walked away with more money.";

    }

}



// A function to randomly shuffle items in an array

function shuffle(myArray) {

    for (var i = myArray.length-1; i >=0; i--) {

     

        var randomIndex = Math.floor(Math.random()*(i+1));

        var itemAtIndex = myArray[randomIndex];

         

        myArray[randomIndex] = myArray[i];

        myArray[i] = itemAtIndex;

    }

}





function getMin(array) {

    return Math.min.apply(0, array);

}



function getMax(array) {

    return Math.max.apply(0, array);

}
 
Advertisement
First of all, your code is already well organized into functions. So good job there.

Right away I see you are using Object.create(boxObject) to instantiate you boxes. I would suggest do it like this instead

// pass initial values in the constructor
function Box(id, value)
{
    this.boxID = id;
    this.boxValue = value;
    this.boxNo = undefined;
    this.open = false;
}
Then to create the box you have
// parseInt not needed since i is already a number
boxArray[i] = new Box(i + 1, money[i]);
Once you have the object you can add functions to the object. When you have a class, like Box, don't directly assign values into the box. For example, you could have an openBox function
Box.prototype.openBox = function()
{
    this.open = true;
}

// to open the box
boxArray[selectedBoxIndex].openBox();
Other possible objects you could use.
GameBoard - contains a list of suitcases and has methods for picking a suitcase, updating the suitcases visually on the screen
Game - basically take all of your globals you have and wrap them up in a game class. To create a game, you pass in an array of money values, and other values that you want adjustable.

The way you have the game is pretty simple, so adding to many classes would likely be over engineering it.
My current game project Platform RPG

Thanks Happy Coder, that gives me plenty to check out.

I don't understand it all yet smile.png but at least now I know what to investigate.

This topic is closed to new replies.

Advertisement