javascript for loop to use a function for several objects - javascript

I am working on a game that has three dice cubes that show random faces upon clicking a button.
Images are by css image sprite. If the random number gets 1 the dice cube is assigned to a css class that has its image sprite.
function diceroll (){
var randomnumber = Math.floor(Math.random() * (6 - 1 + 1)) + 1;
switch (randomnumber) {
case 1:
document.getElementById("dice1").setAttribute("class", "face1");
break;
case 2:
document.getElementById("dice1").setAttribute("class", "face2");
break;
case 3:
document.getElementById("dice1").setAttribute("class", "face3");
break;
case 4:
document.getElementById("dice1").setAttribute("class", "face4");
break;
case 5:
document.getElementById("dice1").setAttribute("class", "face5");
break;
case 6:
document.getElementById("dice1").setAttribute("class", "face6");
break;
}
}
I have a separate button, when clicked it should run the above diceroll function to the three divs with ids dice1, dice2 and dice3.
I want to use
function gotoloop (){
for (i = 0; i < 2; i++) {
// the code that affects dice(n) and n=1 and then diceroll function
// affects dice1 n+1
}
}
I researched and could not find a way to implement the code for the last commented two lines. Please let me know if my approach is correct and help me with the code.

If I understood your question correcly, you want something like this:
function diceroll (diceId){
var randomnumber = Math.floor(Math.random() * 6) + 1;
switch (randomnumber) {
case 1: document.getElementById(diceId).setAttribute("class", "face1"); break;
case 2: document.getElementById(diceId).setAttribute("class", "face2"); break;
case 3: document.getElementById(diceId).setAttribute("class", "face3"); break;
case 4: document.getElementById(diceId).setAttribute("class", "face4"); break;
case 5: document.getElementById(diceId).setAttribute("class", "face5"); break;
case 6: document.getElementById(diceId).setAttribute("class", "face6"); break;
}
}
function gotoloop (){
// Start loop at i=1 because the first ID is dice1
for (var i = 1; i <= 3; i++) {
// the code that affects dice(n) and n=1 and then diceroll function affects dice1
// n+1
diceroll("dice" + i);
}
}
Or as per Marc Baumbach's comment, you could write:
function diceroll (diceId){
var randomnumber = Math.floor(Math.random() * 6) + 1;
document.getElementById(diceId).setAttribute("class", "face" + randomnumber);
}

Related

How can i check two variables in a switch-case statement?

The question is something like this.
You are given a cubic dice with 6 faces. All the individual faces have a number printed on them. The numbers are in the range of 1 to 6, like any ordinary dice. You will be provided with a face of this cube, your task is to guess the number on the opposite face of the cube.
Ex:
Input:
N = 6
Output:
1
Explanation:
For dice facing number 6 opposite face
will have the number 1.
I did it using a normal switch-case by checking all six faces and returning the respective die face number value, which passed my test cases. However, I need to simplify the code. Is it possible for me to do so?
oppositeFaceOfDice(N) {
//code here
switch(N){
case 1:return 6;
break;
case 6:return 1;
break;
case 2:return 5;
break;
case 5:return 2;
break;
case 3:return 4;
break;
case 4:return 3;
break;
default: return -1;
}
}
oppositeFaceOfDice(N) {
switch(N){
case 1||6 : return 6?1:6;
break;
case 2||5: return 2?5:2;
break;
case 3||4: return 4?3:4;
break;
}
}
Use an object literal instead of a switch statement:
function oppositeFaceOfDice(N) {
return {1: 6, 2: 5, 3: 4, 4: 3, 5: 2, 6: 1}[N];
}
Or use #DavidThomas' suggestion above which is particularly clever:
function oppositeFaceOfDice(N) {
if(N < 1 || N > 6) return undefined;
return 7 - N;
}
Other than rewriting the codes, since in your case, the codes are very clear and easy to debug, you can remove the break statement since it's not necessary.
oppositeFaceOfDice(N) {
//code here
switch(N){
case 1:return 6;
case 6:return 1;
case 2:return 5;
case 5:return 2;
case 3:return 4;
case 4:return 3;
}
}

Card Counting with Switch instead of If Else if. Why do I not need to also use RETURN?

I'm a beginner in javascript, so apologies in advanced if this is a dumb question. So, I've noticed that this question has been asked before, but that question was using IF ELSE statements. I'm trying to do it with SWITCH instead.
What i wanted to know is whether i need to also type in RETURN before count++ or count-- inside the SWITCH. I was using a website that provided this question, and my only error was that i used RETURN. The other post used IF ELSE IF and used RETURN.
Can anybody explain why i didn't need to use RETURN?
let count = 0;
function cc(card) {
switch (card){
case 2:
case 3:
case 4:
case 5:
case 6:
count++;
break;
case 7: case 8: case 9:
count;
break;
case 10: case "J": case "Q": case "K": case "A":
return count--;
break;
}
if (count>0){
return count+" Bet";
} else {
return count+" Hold";
}
}
Update
Do not add return to a switch()'s case block
Interrupting the flow gives you no advantage and more than likely error prone code that will not log any runtime errors.
In Example C are three functions:
Function
Description
Icon
A(card)
The original version of cc(card) without the added returns
👍
B(card)
The modified version of cc(card) with returns short circuiting each case
⛔
C(card)
The modified version of B(card) with prefixed operators that fix B(card)
⚠️
switch() is Fragile
A return before the break is a short circuit. Short circuit in programming context is inserting an early termination of a function/method when a condition is meet. I use this technique frequently but never in a switch(). switch() is a very readable yet bulky function if you deviate from how it's normally used it will usually cause a hiccup -- something inaccurate or incorrect and too slight to notice since it's not a runtime error.
Take for instance the line marked with a warning sign ⚠️ in Example A (also abstracted in Figure I)
Figure I
return count--;
break;
So any 10 or face card is short circuited so it never reaches break nor will it reach the last condition that determines whether to bet
or hold which is the whole point of this function. Now if we were to pass an A♤:
Figure II
cc('A');
// returns a 0 / expected -1
Why did it not decrement count? Because it never got the chance to be evaluated due to being short circuited. Originally, all cards went through the switch got it's value then when it reached the last condition, it would be evaluated and it's current values set to 1, 0, or -1. If you have your heart set on using returns before a break, change the counters from post to pre (see Figure III).
Figure III
return ++counter;
When the in/decrement is prefixed to the value, it is evaluated before it's stored so you'll get accurate results. Like I said, there's no point in using the switch() if return is used within it.
Example A is the OP (Original Post)
Example B is a refactor of OP
Example C is a side-by-side comparison between OP with short circuit 👎 and OP without short circuit 👍
Example A
Original Answer
let count = 0;
function cc(card) {
switch (card) {
case 2:
case 3:
case 4:
case 5:
case 6:
count++;
break;
case 7:
case 8:
case 9:
count;
break;
case 10:
case "J":
case "Q":
case "K":
case "A":
return count--; // ⚠️
break;
}
if (count > 0) {
return count + " Bet";
} else {
return count + " Hold";
}
}
console.log(cc('A'));
Example B
More Blackjack Rules Applied
/**
* #desc - Formats output to console
* #param {any} data - Limited like JSON
*/
const msg = data => console.log(JSON.stringify(data));
/**
* #desc - Given an unknown amount of numbers and
* strings that represent a set of 52 playing
* cards, it'll calculate:
* score points[0]
* hint points[1]
* aces points[2]
* #param {array<rest>} cards - One or more numbers and
strings.
* #return {array<number>} An array of 3 numbers
* see #desc
*/
const score = (...cards) => {
let tuple = [...cards].reduce((points, current) => {
points[0] += current === 'A' ? 11 : typeof current == 'string' ? 10 : current;
points[1] += current < 7 ? 1 : current > 9 ? -1 : 0;
return points;
}, [0, 0]);
let aces = [...cards].filter(c => c === 'A').length;
tuple.push(aces);
return tuple;
}
/**
* #desc - Given an array of 3 numbers, it calculates,
* adjusts, and determines the flow of a
* blackjack game
* #param {array<number>} score - The output of score()
* #return {string} A msg to inform the player of
* current score, a suggestion of what
* to do next, or when the player busts
*/
const hand = score => {
while (score[0] > 21) {
if (score[2] > 0) {
score[2] -= 1;
score[1] += 1;
score[0] -= 10;
} else {
return msg(`${score[0]}, bust!`);
}
}
if (score[0] === 21) {
return msg('BLACKJACK!');
}
let action = score[1] > 0 ? 'make a wager' : 'stand';
return msg(`${score[0]}, you should ${action}.`);
}
hand(score('A', 4, 10));
hand(score(2, 9, 3, 9));
hand(score(10, 'K'));
hand(score(6, 2));
hand(score('A', 'K'));
Example C
Wrong vs. Right
let count = 0;
let countA = 0;
let countB = 0;
let countC = 0;
function A(card) {
console.info('Test ' + count + ' ============================');
console.log('------------A👍-------------');
console.log('inA: ' + countA + ' Card: ' + card);
switch (card) {
case 2:
case 3:
case 4:
case 5:
case 6:
countA++; // 👍
console.log('A++: ' + countA);
break;
case 7:
case 8:
case 9:
countA; // 👍
console.log('A: ' + countA);
break;
case 10:
case "J":
case "Q":
case "K":
case "A":
countA--; // 👍
console.log('A--: ' + countA);
break;
}
if (countA > 0) {
return countA + " Bet";
} else {
return countA + " Hold";
}
}
function B(card) {
console.log('------------B⛔-------------')
console.log('inB: ' + countB + ' Card: ' + card);
switch (card) {
case 2:
case 3:
case 4:
case 5:
case 6:
console.log('B++: ' + countB);
return countB++; // ⛔
break;
case 7:
case 8:
case 9:
console.log('B: ' + countB);
return countB; // ⛔
break;
case 10:
case "J":
case "Q":
case "K":
case "A":
console.log('B--: ' + countB);
return countB--; // ⛔
break;
}
if (countB > 0) {
return countB + " Bet";
} else {
return countB + " Hold";
}
}
function C(card) {
console.log('------------C⚠️-------------');
console.log('inC: ' + countC + ' Card: ' + card);
switch (card) {
case 2:
case 3:
case 4:
case 5:
case 6:
console.log('--C: ' + countC + '⚠️');
return ++countC; // ⚠️
break;
case 7:
case 8:
case 9:
console.log('C: ' + countC);
return countC; // ⚠️
break;
case 10:
case "J":
case "Q":
case "K":
case "A":
console.log('--C: ' + countC + '⚠️');
return --countC; // ⚠️
break;
}
if (countC > 0) {
return countC + " Bet";
} else {
return countC + " Hold";
}
}
document.forms.bj.oninput = hit;
document.forms.bj.onreset = reset;
function hit(e) {
const IO = this.elements;
let draw = IO.draw.value;
let card = isNaN(draw) ? draw : +draw;
let a = A(card);
let b = B(card);
let c = C(card);
IO.A.value = a;
IO.B.value = b;
IO.C.value = c;
count++;
}
function reset(e) {
count = 0;
countA = 0;
countB = 0;
countC = 0;
}
html {
font: 300 1.5ch/1.2 'Segoe UI';
}
#table {
display: flex;
max-width: max-content;
}
legend {
font-size: 1.25rem;
}
select,
input {
display: inline-flex;
font: inherit;
}
label,
select,
input,
output {
display: block;
margin-bottom: 0.5rem;
}
output {
font-weight: 900;
text-align: center;
}
#B {
color: red;
}
.as-console-row::after {
width: 0;
font-size: 0;
}
.as-console-row-code {
width: 100%;
word-break: break-word;
}
.as-console-wrapper {
min-height: 100% !important;
max-width: 50%;
margin-left: 50%;
}
<form id='bj'>
<fieldset id='table'>
<legend>Blackjack</legend>
<label class='IN'>
<select id='draw'>
<option selected>Draw</option>
<option value='2'>2</option>
<option value='3'>3</option>
<option value='4'>4</option>
<option value='5'>5</option>
<option value='6'>6</option>
<option value='7'>7</option>
<option value='8'>8</option>
<option value='9'>9</option>
<option value='10'>10</option>
<option value='J'>Jack</option>
<option value='Q'>Queen</option>
<option value='K'>King</option>
<option value='A'>Ace</option>
</select>
<input type='reset'>
</label>
<fieldset>
<label>
Original: 👍<br>
<output id='A'> </output>
</label>
<label>
Short Circuits: ⛔<br>
<output id='B'> </output>
</label>
<label>
Short Circuits<br>Prefixed Operators: ⚠️<br>
<output id='C'> </output>
</label>
</fieldset>
</fieldset>
</form>

How to find maximum between two numbers in javascript using switch case?

I am trying to run with this code block but it does not work
Switch (num1>num2) {
case 0:
document.write(num2);
break;
case 1:
document.write(num1);
break;
}
You could use something simple as Math.max(5, 10);
const numOne = 5;
const numTwo = 10;
console.log(`Bigger number is: ${Math.max(numOne, numTwo)}`);
Or if you absolutely 'have to' use switch statement, you can try something like this:
const numOne = 5;
const numTwo = 10;
switch(true) {
case (numOne > numTwo):
console.log(`Bigger number is ${numOne}`);
break;
case (numOne < numTwo):
console.log(`Bigger number is ${numTwo}`);
break;
case (numOne === numTwo):
console.log(`${numOne} is equal to ${numTwo}`);
break;
default: console.log(false, '-> Something went wrong');
}
Logical operations return boolean on Javascript.
document.write writes HTML expressions or JavaScript code to a document, console.log prints the result on the browser console.
switch (num1>num2) {
case true:
console.log(num1);
break;
case false:
console.log(num2);
break;
}
switch (with a lower case s) uses strict comparison === so the value of a boolean like 11 > 10 will never === 0 or 1.
You need to test for the boolean if you want to do it this way:
let num1 = 10
let num2 = 20
switch (num1>num2) {
case false:
console.log(num2);
break;
case true:
console.log(num1);
break;
}
If for some reason you were given numbers you could explicitly cast them to booleans with something like case !!0: but that starts to get a little hard on the eyes.
If your goal is to find the max of two numbers, Math.max(num1, num2) is hard to beat for readability.
You would just use the greater than / less than inside of the switch statement.
var x = 10;
var y = 20;
switch(true) {
case (x > y):
console.log(x);
break;
case ( y > x):
console.log(y);
break;
}

Word search game : grid generating takes too long

I'm working on a Word Search puzzle game, and I'm struggling with generating the grid with letters. At the moment, I'm able to generate the grid, but the performance is very slow (way too slow for a decent usage, it can take up to 30-40 seconds before generating the grid).
To fit words into the grid, I'm using a recursive function that tries to fit the last word from a given list, then the one before it, etc, and if it doesn't fit, backtracks to the previous word and changes its place, then tries again. I guess I'm not doing this right, because it keeps going back and forth.
I tried to use weighed probabilities for directions, so that the generating is made in a "smarter" way, but I'm not getting any results yet.
My question :
How can I optimize this code to make it more performant and reliable? I accept any suggestions, even if it makes me do a lot of changes (if there is an iterative solution for example instead of a recursive one, or if I'm not reasoning correctly in the function...).
Here is the function:
function tryWord(grid, wordList, index, gridLength){
var valid = false;
var clear = false;
if(index==(wordList.length-1)){
/* Clear grid for current index */
for(var j=0; j<gridLength.x; j++){
grid[index][j] = [];
for (var k=0; k<gridLength.y; k++){
grid[index][j][k] = '';
}
}
var nbIterations = 0;
// Try current word
while(valid == false){
// Impossible to resolve this grid
if(nbIterations>500){
return false;
}
nbIterations++;
var initX = Math.floor(Math.random() * gridLength.x); // x coord of first letter of the word
var initY = Math.floor(Math.random() * gridLength.y); // y coord of first letter of the word
var direction = Math.floor(Math.random() * 8); // direction of the word (0=top-left; 1=top; 2=top-right; 3=right; 4=bottom-right; 5=bottom; 6=bottom-left; 7=left)
valid = checkValidWord(wordList[index].length, initX, initY, direction, gridLength);
}
clear = checkClearWord(wordList[index], initX, initY, direction, grid[index]);
if(!clear){
return false;
}
var x = initX;
var y = initY;
for(var j=0; j<wordList[index].length; j++){
grid[index][x][y] = wordList[index].charAt(j);
switch(direction){
case 0:
x--;
y--;
break;
case 1:
y--;
break;
case 2:
x++;
y--;
break;
case 3:
x++;
break;
case 4:
x++;
y++;
break;
case 5:
y++;
break;
case 6:
x--;
y++;
break;
case 7:
x--;
break;
default:
break;
}
}
return grid;
}
else if(index!=(wordList.length-1)){
var emptyGrid = true;
for(var p=0; p<grid[index].length; p++){
for(var q=0; q<grid[index][p].length; q++){
if(grid[index][p][q]!=''){
emptyGrid = false;
}
}
}
if(emptyGrid || $scope.nbIterations>50){
$scope.nbIterations=0;
grid = tryWord(grid, wordList, index+1, gridLength);
}
/* Prepare grid for current index */
grid[index] = grid[index+1];
if(grid!=false){
// Try current word
while(valid == false){
var initX = Math.floor(Math.random() * gridLength.x); // x coord of first letter of the word
var initY = Math.floor(Math.random() * gridLength.y); // y coord of first letter of the word
var direction = Math.floor(Math.random() * 8); // direction of the word (0=top-left; 1=top; 2=top-right; 3=right; 4=bottom-right; 5=bottom; 6=bottom-left; 7=left)
valid = checkValidWord(wordList[index].length, initX, initY, direction, gridLength); // Check that word fits in the grid
}
clear = checkClearWord(wordList[index], initX, initY, direction, grid[index]);
// If word is obstructed by other words
if(!clear){
$scope.nbIterations++;
return tryWord(grid, wordList, index, gridLength); // Try again
}
else{
var x = initX;
var y = initY;
for(var j=0; j<wordList[index].length; j++){
grid[index][x][y] = wordList[index].charAt(j);
switch(direction){
case 0:
x--;
y--;
break;
case 1:
y--;
break;
case 2:
x++;
y--;
break;
case 3:
x++;
break;
case 4:
x++;
y++;
break;
case 5:
y++;
break;
case 6:
x--;
y++;
break;
case 7:
x--;
break;
default:
break;
}
}
return grid;
}
}
else{
return false;
}
}
}
Parameters of the function :
grid : at the beginning, just a 10x11x11 array filled with '' string.
wordList : an array of words to put in the grid
index : 0 when calling the function for the first time, then it's used to check how deep we are in the wordList
gridLength : an array : {x:11, y:11}, giving the grid length
Some more precisions about the function :
The function checkValidWord checks if a given word going to a given direction fits in a grid with a given size. Returns true or false.
The function checkClearWord checks if a given word going to a given direction fits in the grid with other words already in it (no obstruction etc). Returns true or false.
The function tryWord is supposed to output a 3-dimensional array of size [wordList.length;11;11]. I then use the grid[0] as my 2 dimensional grid for the game.

getElementId('divname' + varname) ::: Not Working?

I have a long set of divs where I'd like to change all of their background colors to a random color when someone clicks the "home" button with a cascading delay (which I'll add later). I've been testing this in jfiddle and I can't seem to get it to work.
For example, with a while loop of 1-10 on jsfiddle:
http://jsfiddle.net/PWvaw/17/
Am I having a var scope issue or is there an issue with placing a string/variable combo in a getElementByID method? It seems to show, when I place head tags in the HTML section of jfiddle, the code turns red right after the "getElementById("
switch (randomNumberOne) {
case 1:
document.getElementById(
Any help would be appreciated. I did a search here already and found nothing conclusive, however, I apologize if I missed an answer. Thanks!
Just remove the semicolon in your color codes.
function backgroundColorChange() {
var num = 1;
while (num <= 10) {
var randomNumberMe = Math.floor((Math.random()*10)+1);
console.log(randomNumberMe);
switch (randomNumberMe) {
case 1:
document.getElementById('r' + num).style.backgroundColor = '#db0058';
break;
case 2:
document.getElementById('r' + num).style.backgroundColor = '#80e800';
break;
case 3:
document.getElementById('r' + num).style.backgroundColor = '#ffb700';
break;
case 4:
document.getElementById('r' + num).style.backgroundColor = '#4b5ed7';
break;
default:
document.getElementById('r' + num).style.backgroundColor = '#ffffff';
break;
}
num += 1;
}
}
jsfiddle

Categories

Resources