Hunter Hunter - 2 months ago 7
HTML Question

How to change cases in a switch statement once one case condition is met?

I'm trying to figure out how to switch between cases in Javascript/jQuery. I'm creating a dice game where the player needs to roll the dice until they finish the "Phase". Once they finish the "Phase" they will move onto the next "Phase" and any previous "Phases" won't interfere with the current "Phase". There will be several different "Phases" where they start at "Phase 1" and work down to "Phase 2" and so on until the last phase. Is there any way I can work down the "Phases"? I'm trying a switch statement here with no success. If a switch statement won't do the job, what will?

//Start of Dice Code
var die1Array = [];
var die2Array = [];
var die3Array = [];

var die1 = function() {
var roll1 = Math.floor(Math.random() * 6) + 1;
if(roll1 === 1) {
die1Array.push(1);
}
else if(roll1 === 2) {
die1Array.push(2);
}
else if(roll1 === 3) {
die1Array.push(3);
}
else if(roll1 === 4) {
die1Array.push(4);
}
else if(roll1 === 5) {
die1Array.push(5);
}
else if(roll1 === 6) {
die1Array.push(6);
}
};

var die2 = function() {
var roll2 = Math.floor(Math.random() * 6) + 1;
if(roll2 === 1) {
die2Array.push(1);
}
else if(roll2 === 2) {
die2Array.push(2);
}
else if(roll2 === 3) {
die2Array.push(3);
}
else if(roll2 === 4) {
die2Array.push(4);
}
else if(roll2 === 5) {
die2Array.push(5);
}
else if(roll2 === 6) {
die2Array.push(6);
}
};

var die3 = function() {
var roll3 = Math.floor(Math.random() * 6) + 1;
if(roll3 === 1) {
die3Array.push(1);
}
else if(roll3 === 2) {
die3Array.push(2);
}
else if(roll3 === 3) {
die3Array.push(3);
}
else if(roll3 === 4) {
die3Array.push(4);
}
else if(roll3 === 5) {
die3Array.push(5);
}
else if(roll3 === 6) {
die3Array.push(6);
}
};
//End of Dice Code


var main = function() {

$("#roll").on("click", die1);
$("#roll").on("click", die2);
$("#roll").on("click", die3);
$("#roll").on("click", die4);
$("#roll").on("click", die5);
$("#roll").on("click", die6);

//Where I want to switch between cases.
//Once Phase 1's condition (the if statement) is met, I want to switch to Phase 2.
var lvls = 1;
switch(lvls) {
case 1:
alert("Phase 1");
$("#submit").click(function() {
if((die1Array.slice(-1)=="1"||die2Array.slice(-1)=="1"||die3Array.slice(-1)=="1")&&(die1Array.slice(-1)=="2"||die2Array.slice(-1)=="2"||die3Array.slice(-1)=="2")&&(die1Array.slice(-1)=="3"||die2Array.slice(-1)=="3"||die3Array.slice(-1)=="3")) {
alert("Completed Phase 1: Straight of 3");
lvls = 2;
return lvls;
}
else {
alert("Phase 1: Straight of 3. Not Complete. Try again.");
};
});
break;

case 2:
alert("Phase 2");
//Phase 2's code
break;

//Additional cases/Phases would go here.
default:
};

};


$(document).ready(main);

Answer

In your die# function you could just push the values without the if else part.

var die1 = function () {
    var roll1 = Math.floor(Math.random() * 6) + 1;
    die1Array.push(roll1);
}

Or more general:

var die = function (dieArray) { dieArray.push(Math.floor(Math.random() * 6) + 1); }

Using:

die(die1Array); die(die2Array); die(die3Array); ...

The issue of your current swithc is that you bind an event handler function inside a case.

If you want that event handler work only in a particular state, you should set a state variable to save the current state and check this variable in the handler function.

var main = function () {
    var diceState = 1;

    $("#submit").click(function() {
            if (diceState === 1) {
                // do something
            }
        });

    switch(lvls) {
    case 1:
          diceState = 1;
          break;

    case 2: 
         diceState = 2;
         break;
    }

The other problem you have is that you set the value of lvls to 1 in the main function and so you will have only 1 case, the other changes of lvls will have no effect at all, even you call main again.

If you call main more than one time, then you have the problem you're continuosly binding event onsubmit, so each time you submit the form, the function handler is called many times.

You should move the switch statement in a different function, passing the state variable as parameter, and call each time you want to change the state.

So here an example:

// Should be in same scope of the function
// or an attribute of an object to be passed by reference.
var diceState;

var changeState = function (state) {
    switch(state) {
    case 1:
        diceState = 1;
        break;
    ....
    default:
        throw new Error("State " + state + " not supported");
    }
}

And is a good practice to use the default case to handle unexpected values.

Here a suggestion on how to change your main function:

var main = function() {

    var lvls;

    $("#roll").on("click", die1);
    $("#roll").on("click", die2);
    $("#roll").on("click", die3);
    $("#roll").on("click", die4);
    $("#roll").on("click", die5);
    $("#roll").on("click", die6);

    var changeState = function (state) {
        switch(state) {
        case 1:
            alert("Phase 1");
            lvls = state;
            break;

        case 2:
            alert("Phase 2");
            //Phase 2's code
            lvls = state;
            break;

        //Additional cases/Phases would go here.
        default:
        };
    }

    // bind the event handler
    $("#submit").click(function() {
if((die1Array.slice(-1)=="1"||die2Array.slice(-1)=="1"||die3Array.slice(-1)=="1")&&(die1Array.slice(-1)=="2"||die2Array.slice(-1)=="2"||die3Array.slice(-1)=="2")&&(die1Array.slice(-1)=="3"||die2Array.slice(-1)=="3"||die3Array.slice(-1)=="3")) {
                alert("Completed Phase 1: Straight of 3");
                changeState(2);

                // you could not return the vaue here!
                // return lvls; 
            }
            else {
                alert("Phase 1: Straight of 3.  Not Complete.  Try again.");
            };
        });

     changeState(1);

};
Comments