I would like some advice on how to slim down this switch:
switch (lotUser | winningLot) {
case lotUser === winningLot[0]:
case lotUser === winningLot[1]:
case lotUser === winningLot[2]:
case lotUser === winningLot[3]:
case lotUser === winningLot[4]:
case lotUser === winningLot[5]:
case lotUser === winningLot[6]:
case lotUser === winningLot[7]:
console.log("You win!");
break;
default:
console.log("You do not win!");
break;
}
Instead of
case lotUser === winningLot[0]:
I wrote the script to be:
switch (lotUser | winnendLot) {
case lotUser === winnendLot[0|1|2|3|4|5|6|7]:
console.log("You win!");
break;
default:
console.log("You do not win!");
break;
}
I just don't know if this works the way I want it to work. It needs to check if the generated lotUser is equal to one of the values in an array (winningLot). If the lotUser equals one or more of the values in the winningLot array, it should output "You win!".
Could someone please confirm that my code does the description I gave?
What about Array.prototype.indexOf()?
if (winnedLot.indexOf(lotUser) !== -1) {
console.log("Won!");
}
else {
console.log("Lost!");
}
It searches the array for the first occurrence of the value stored in lotUser and returns its respective index.
Since you do not need to count the occurrences, this should be the best way.
If you want to count them, use a loop:
var count = 0;
for (var i=0, len=winnedLot.length; i<len; i++) {
if (winnedLot[i] === lotUser) {
count++;
}
}
You can simply use indexOf:
if(winningLot.indexOf(lotUser) >= 0) {
...
} else {
...
}
Well for starters you're using switch incorrectly. The value to compare goes in the switch(...) part, and the possible values are listed by each case ...:
Anyway, that aside, all you want is to check if lotUser is in the winnendLot array. Easy:
// assuming supporting browser:
if( winnendLot.indexOf(lotUser) > -1) console.log("You win!");
// full browser support:
var winner = false, l = winnendLot.length, i;
for( i=0; i<l; i++) {
if( winnendLot[i] === lotUser) {
winner = true;
break;
}
}
if( winner) console.log("You won!");
Related
I have a simple problem: I need to roll two sets of dice. For each number possible in the first roll, there are a set of conditionals that I then check against the second roll. The conditionals for each roll are different.
The problem, to me, is that something like this repeated roughly thirty times seems like a gross thing to stick in my code:
if (roll == 3) {
if (secondRoll < 5) {
do this
}
else if (secondRoll > 5 && secondRoll < 10) {
do this
}
else {
do this
}
}
if ...... and so on
So what do I do? Is there a more elegant way to do this? I've thought about something like this:
class Result {
constructor(firstRoll, secondRollMin, secondRollMax, output) {
this.firstRoll;
this.secondRollMin;
this.secondRollMax;
this.output;
}
}
and then checking the rolls against matching properties in a set of objects, but I'm not sure that's honestly any better. Any thoughts would be appreciated.
Just a small improvement, but you only need to check the upper bound of the range in each subsequence else if:
if (roll == 3) {
if (secondRoll < 5) {
do this
}
else if (secondRoll < 10) { // secondRoll must be >= 5 already
do this
}
else {
do this
}
}
Use Switch to simplify
switch (roll) {
case 1-4:
// Do something.
break;
case 5-8:
// Do something.
break;
case 9-11:
// Do something.
break;
default:
break;
}
How about creating a key for the combination and a bit simpler if/else? You could combine any combination that has the same action.
const combo = `${roll}-${secondRoll}`;
if (['1-1', '1-2', '1-3', '3-4', '3-5', '3-6'].includes(combo) {
// Do this
} else if (['1-4', '1-5', '1-6', '3-1', '3-2', '3-3'].includes(combo) {
// Do this
// ...
} else if (['6-4', '6-5', '6-6'].includes(combo) {
// Do this
}
Or create a switch/case:
const combo = `${roll}-${secondRoll}`;
switch (combo) {
case '1-1':
case '1-2':
case '1-3':
case '3-4':
case '4-5':
case '5-6':
// Do this
break;
case '1-4':
case '1-5':
case '1-6':
case '3-1':
case '4-2':
case '5-3':
// Do this
break;
// ...
case '6-4':
case '6-5':
case '6-6':
// Do this
break;
}
You can try a mixture of if, else and switch blocks. You can use different methods to call based on the first roll. A switch statement is usually more efficient than a set of nested ifs.
class Result {
constructor(firstRoll, secondRollMin, secondRollMax, output) {
this.firstRoll;
this.secondRollMin;
this.secondRollMax;
this.output;
switch(firstRoll){
case 1:
this.output = oneToXTime(secondRollMin,secondRollMin)
break;
case 2:
this.output = twoToXTime(secondRollMin,secondRollMax)
break;
case 3:
this.output = threeToXTime(secondRollMin,secondRollMax)
break;
case 4:
this.output = fourToXTime(secondRollMin,secondRollMax)
break;
case 5:
this.output = fiveToXTime(secondRollMin,secondRollMax)
break;
case 6:
this.output = sixToXTime(secondRollMin,secondRollMax)
break;
}
}
static String oneToXTime(secondRollMin,secondRollMin) {
String result = ""
if (secondRollMin < 5) {
result = "My result"
}
else if (secondRollMin < 10) {
result = "My result 2"
}
return result
}
static String twoToXTime(secondRollMin,secondRollMin) {
String result = ""
if (secondRollMin < 5) {
result = "My result"
}
else if (secondRollMin < 10) {
result = "My result 2"
}
return result
}
static String threeToXTime(secondRollMin,secondRollMin) {
// Same as above...
}
static Stfing fourToXTime(secondRollMin,secondRollMin) {
// Same as above...
}
static String fiveToXTime(secondRollMin,secondRollMin) {
// Same as above...
}
static String sixToXTime(secondRollMin,secondRollMin) {
// Same as above...
}
}
Is it possible to use nested switch statement in javascript.
My code is some what look like
switch(id1)
{
case 1:
switch(id2){
case 1:{
switch(id3){
case 1:{}
case 2:{}
}
}
case 2:{
switch(id4){
case 1:{}
case 2:{}
}
}
}
case 2:
}
If yes then it is a good practice to do or we can use any alternate approach.
Your approach is absolutely fine.
You can make the switch nesting less complex by using switch (true):
switch (true) {
case ((id1 === 1) && (id2 === 1) && (id3 === 1)) :
case ((id1 === 1) && (id2 === 1) && (id3 === 2)) :
case ((id1 === 1) && (id2 === 2) && (id3 === 1)) :
case ((id1 === 1) && (id2 === 2) && (id3 === 2)) :
case ((id1 === 2) && (id2 === 1) && (id3 === 1)) :
case ((id1 === 2) && (id2 === 1) && (id3 === 2)) :
case ((id1 === 2) && (id2 === 2) && (id3 === 1)) :
case ((id1 === 2) && (id2 === 2) && (id3 === 2)) :
}
Yes, you can use inner switch like this way,
Please check this demo : https://jsfiddle.net/1qsfropn/3/
var text;
var date = new Date()
switch (date.getDay()) {
case 1:
case 2:
case 3:
default:
text = "Looking forward to the Weekend";
break;
case 4:
case 5:
text = "Soon it is Weekend";
break;
case 0:
case 6:
switch(date.getFullYear()){
case 2015:
text = "It is Weekend of last Year.";
break;
case 2016:
text = "It is Weekend of this Year.";
break;
case 2017:
text = "It is Weekend of next Year.";
break;
default:
text = date.getDay();
break;
}
break;
}
document.getElementById("demo").innerHTML = text;`
You can use a nested switch statement but that can quickly become a spaghetti code and therefore it is not recommended. I would rather use functions with the nested switch statement for code clearance or maybe use recursive function depending on what the code is supposed to do.
This is only a pseudo-code but I hope it gives you some idea on how to implement it. You have to be carefull to make the recursion stop on some given value of the ID.
This pseudo-code increments the value of the ID by 1 if the value of the ID is 1, and increments by 2 if the value is 2. If the value is not 1 or 2 the recursion ends.
function recursiveSwitch(var id) {
switch(id) {
case 1:
recursiveSwitch(id + 1);
break;
case 2
recursiveSwitch(id + 2)
break;
default:
return;
}
}
Basically, it's possible but I think it depends on the complexity of the nesting if it's recommended to use nested switch statement or to use functions with the nested switch statement as Ómar Óskarsson has suggested.
I got a function that should return a result depending on a dealed Black Jack hand. I used a switch statement for this, eventhough I'm not sure you could use multiple switch in a function. Anyhow I got an error saying 'missing ; before statement' after the first 'result' text in the first 'case'. This code is what I have been taught so I'm not sure where I did go wrong. Could you please give me a hint or anything, please? Refards, Thomas.
function printResult(playResult, dealResult) {
var text = "";
switch(playResult) {
case (playResult == 21) : result "black jack";
break;
case (playResult > 21) : result "busted";
break;
case (playResult < 21) : result "safe";
break;
}
switch(dealResult) {
case (dealResult < 17) : result "safe";
break;
case (dealResult == 17 && < 21) : result "stop";
break;
case (dealResult == 21) : result "black jack";
break;
}
return result;
}
var result = "Player: " + playResult + ", Dealer: " + dealResult;
ANSWER = (printResult(5+9+10, 6+3+7));
Maybe you want result to be a variable assigment?
result = "black jack"
or maybe a return?
return "black jack"
It looks like you're trying to do "if logic" in the case statement; that's not how a switch works. A switch is going to take the value of dealResult and do a straight compare.
switch(dealResult)
{
case 21: //dealResult MUST be 21
result = 'blackjack!'
break;
case 20: //dealResult MUST be 20
//etc..
break;
case >20: //not valid, will break
}
As far as I know, if you need to do > and < compares, you should be using an if -> else block.
You have to remove all of the playResult variables inside of the switch block.
In addition, switch does not support higher than or lower than so a if is better suited for this situation.
function printResult(playResult, dealResult) {
var result;
if(playResult == 21) {
result = "black jack";
} else if(playResult > 21) {
result = "busted";
} else {
result = "safe";
}
if(dealResult < 17) {
result = "stop";
} else if(dealResult == 17 && dealResult < 21) {
result = "stop";
} else {
result = "black jack";
}
return result;
}
var result = "Player: " + playResult + ", Dealer: " + dealResult;
ANSWER = (printResult(5+9+10, 6+3+7));
This is a lot closer, but there is still problems with your logic.
Looking at your function, even if you get the switch working i don't think the logic is what you're aiming it to be.
If the purpose of the function is tell you who won the game, ergo the result as your name implies then you need to first put the rules down.. lets just for readability write it in pseudo..
Where either player has blackjack check the following
Player Blackjack to Dealer Blackjack = Push (Draw)
Player Blackjack to Dealer Anything = Player Win
Player Anything to Dealer Blackjack = Dealer Win
Then check if one is bust, to win a player must of held
Player > 21 = Dealer Win
Player <=21 and Dealer > 21 = Player Win
After that, we can do the simple checks.
Player == Dealer = Push
Player > Dealer = Player Win
Player < Dealer = Dealer Win
You can't really use a switch statement effectively to do this. You 'can' use it but for something like this, if else will suffice.
function blackJackWinnerIs(player, dealer)
{
if((player == 21) || (dealer==21))
{
if(player > dealer)
return "Player";
else if (player < dealer)
return "Dealer";
else
return "Push";
}
else if(player > 21)
return "Dealer";
else if(dealer > 21) // already checked if player<=21
return "Player";
else if(player > dealer)
return "Player";
else if(dealer > player)
return "Dealer";
else return "Push";
}
var hands = [
{player:21,dealer:21},
{player:20,dealer:21},
{player:21,dealer:17},
{player:22,dealer:17},
{player:17,dealer:22},
{player:19,dealer:18},
{player:18,dealer:20},
{player:20,dealer:20}
];
for(var i=0; i<hands.length;i++)
{
var winner = blackJackWinnerIs(hands[i].player,hands[i].dealer);
console.log("Player:",hands[i].player," Dealer:",hands[i].dealer," => Winner:",winner);
}
This is functional.. but it won't protect you from bad inputs e.g. if you accidentally passed in two nulls you would get a "push" result when really you should either send out an error or void the game... but thats all on you.
I am creating a minesweeper game for a javascript project and have run into a problem that I can't get my head round. When you click on an empty cell (one which does not have any mines around it and so does not display a number) in the minesweeper game for those who don't know, this will reveal the whole block of empty cells that are neighbouring eachother, stopping when the "wall of numbers" containing these empty blocks is found. Example below:
[1]http://datagenetics.com/blog/june12012/hole.png
This requires a recursive function to figure out which blocks are to be revealed. My code at the moment only reveals the block that is clicked on:
function revealGridContents()
{
switch (positionClickContents)
{
case 0:
ctx.drawImage(clickedImage, (xClick*20), (yClick*20));
break;
case 1:
ctx.drawImage(num1Image, (xClick*20), (yClick*20));
break;
case 2:
ctx.drawImage(num2Image, (xClick*20), (yClick*20));
break;
case 3:
ctx.drawImage(num3Image, (xClick*20), (yClick*20));
break;
case 4:
ctx.drawImage(num4Image, (xClick*20), (yClick*20));
break;
case 5:
ctx.drawImage(num5Image, (xClick*20), (yClick*20));
break;
case 6:
ctx.drawImage(num6Image, (xClick*20), (yClick*20));
break;
case 7:
ctx.drawImage(num7Image, (xClick*20), (yClick*20));
break;
case 8:
ctx.drawImage(num8Image, (xClick*20), (yClick*20));
break;
};
};
The number passed into the switch statement is the value of the data in the array grid[xClick][yClick]; eg a 4 symbolises a block with 4 mines around it, so the image for 4 will be displayed.
Case 0 is the case that a blank block is clicked and so the code for this needs modifying but I really can't think what to do.
From what I can understand, I will need to call the revealGridContents(); function from case 0, but passing in new values for xClick and yClick (the x and y values of the array position) for each square that I want to check.
Any help shedding the light on what I need to do next would be greatly appreciated!
Without knowing slightly more of your program it's hard to give you an exact solution. You'll probably need a separate function to do this, as just using the same function will reveal everything (which is obviously not how the game works). You'll also need some way of keeping track of revealed cells, otherwise you'll get into a loop (I'm assuming this is stored in another 2d array revealed[x][y]).
You probably want to do something like this (I haven't tested this so there may be errors in it - apologies):
function revealGridContents(){
switch (positionClickContents){
case 0:
ctx.drawImage(clickedImage, (xClick*20), (yClick*20));
checkAdjacentCells(xClick, yClick);
break;
...
}
}
function checkAdjacentCells(x,y){
var cellsToCheck = [
[x,y+1],
[x,y-1],
[x+1,y],
[x-1,y]];
var x,y;
for(var i=0; i<=cellsToCheck.length; i++){
x = cellsToCheck[i][0];
y = cellsToCheck[i][1];
if(!revealed[x][y] && grid[x][y] == 0){
ctx.drawImage(clickedImage, x*20, y*20);
checkAdjacentCells(x,y);
}
}
}
Just as a general advice, you need a better separation between the model of your game and the UI.
Here is the begining of my interpretation of the minesweeper game:
function init() {
var i,j; // indexes
map = []; // global map, because i'm lazy
for (i=0; i<10; i++) {
var row = [];
for (j=0; j<10; j++)
row.push({
bomb : Math.round(Math.random()-0.4), // set bombs randomly, change to your correct ratio
revealed : false, // nothing is visible at start
count : 0 // counts will be computed after all the map is created
});
map.push(row);
}
// set adjacent bomb counts
for (i=0; i<10; i++)
for (j=0; j<10; j++) {
if (map[i-1] && map[i-1][j-1] && map[i-1][j-1].bomb) map[i][j].count++;
if (map[i-1] && map[i-1][j] && map[i-1][j].bomb) map[i][j].count++;
if (map[i-1] && map[i-1][j+1] && map[i-1][j+1].bomb) map[i][j].count++;
if (map[i] && map[i][j-1] && map[i][j-1].bomb) map[i][j].count++;
if (map[i] && map[i][j+1] && map[i][j+1].bomb) map[i][j].count++;
if (map[i+1] && map[i+1][j-1] && map[i+1][j-1].bomb) map[i][j].count++;
if (map[i+1] && map[i+1][j] && map[i+1][j].bomb) map[i][j].count++;
if (map[i+1] && map[i+1][j+1] && map[i+1][j+1].bomb) map[i][j].count++;
}
}
function print() { // uses console to display instead of canvas
var output = '\n';
for (var i=0; i<10; i++) {
for (var j=0; j<10; j++) {
var item = map[i][j];
output += (item.revealed ? item.count : 'x') + ' ';
}
output += '\n';
}
console.log(output);
}
function click(x,y) {
reveal(x,y);
print(map);
}
function reveal(x,y) {
// break early if click is invalid (invalid clicks are generated)
if (x < 0 || x > 9 || y < 0 || y > 9 || map[x][y].revealed) return;
// mark the square as clicked
map[x][y].revealed = true;
if (map[x][y].bomb) { // losing click
console.log('You lost');
} else if (map[x][y].count === 0) { // click on 0 adjacent bombs
reveal(x-1, y);
reveal(x, y-1);
reveal(x, y+1);
reveal(x+1, y);
}
}
init();
console.log('First print');
print();
console.log('Click 1,3');
click(1,3);
The difficult part is in the click() function.
Try this demo (click 'run with JS' several times until you don't lose and hit a 0):
http://jsbin.com/iqeganU/1/edit
I found this example to make range work with switch statement:
function GetText(value)
{
var result;
switch (true)
{
case ((value >= 26) && (value <= 50)):
result = ">= 26.";
break;
case ((value >= 1) && (value <= 25)):
result = "Between 1 and 25.";
break;
case (value == 0):
result = "Equals Zero.";
break;
}
return result;
}
But if I modify the code and remove the second check for the value the example will still work:
function GetText(value)
{
var result;
switch (true)
{
case ((value >= 26)):
result = ">= 26 .";
break;
case ((value >= 1)):
result = "Between 1 and 25.";
break;
case (value == 0):
result = "Equals Zero.";
break;
}
return result;
}
So if I passed 29 even that I have two true cases the first one will be selected. My question is that how switch statement works in most of programming languages it will start comparing from the top or its only in this case (and is it good or bad to write it like that?).
switch statement checks for matches from top to bottom.
From MDN docs on switch statement:
If a match is found, the program executes the associated statements. If multiple cases match the provided value, the first case that matches is selected, even if the cases are not equal to each other.
I would do something like this (with if and else if chains):
function GetText(value) {
var result;
if (value == 0) {
result = "Equals Zero.";
} else if (value <= 25) {
result = "Between 1 and 25.";
} else if (value <= 50) {
result = "Between 26 and 50.";
}
return result;
}