Javascript: Some Variables Defined, Some Undefined - javascript

I am writing a basic casino javascript game that will randomly pick 3 numbers 1-10. If each number is 7, it will display an alert box saying 'You Win!'. In the function below:
function StartSpin(){
var one;
var two;
var three;
var cone;
var ctwo;
var cthree;
var one = Math.floor((Math.random() * 10) + 1);
var two = Math.floor((Math.random() * 10) + 1);
var three = Math.floor((Math.random() * 10) + 1);
if(one == 1){var cone = "Ace";}
if(two == 1){var ctwo = "Ace";}
if(three == 1){var cthree = "Ace";}
document.getElementsByClassName("Spinner")[0].innerHTML= cone
document.getElementsByClassName("Spinner")[1].innerHTML= ctwo
document.getElementsByClassName("Spinner")[2].innerHTML= cthree
}
On the actual page before clicking the button to start randomizing it says:
--|--|--. When clicking it, it sets the --'s to the randomized number. Every number/-- set says undefined except sometimes one will say 'Ace' meaning it was 1. So it might say: undefined|Ace|undefined, or undefined|undefined|undefined, etc.
Here is the HTML:
<div id="GameOne">
<h1>~ Game One ~</h1>
<h2>Try to get three 7's!</h2>
<span class="so Spinner">--</span> |
<span class="st Spinner">--</span> |
<span class="sth Spinner">--</span>
<br/>
<button id="SpinButton" onclick="StartSpin()">Spin!</button>
</div>
EDIT: I re-defined variables to see if that would help the undefined problem(In the javascript code fyi)

The short answer is you are only giving your variables values other than undefined if you randomly get the number 1. Otherwise they stay undefined - which is the default value of variables in JavaScript.
Here's some seriously cleaned up logic:
http://jsbin.com/milibusaxe/1/edit?html,js,output
function roll() {
var n = Math.floor((Math.random() * 10) + 1);
return (n === 1 ? 'Ace!' : n);
}
function StartSpin(){
var slots = document.getElementsByClassName("Spinner");
for (var i = 0, e = slots.length; i < e; i++) {
slots[i].innerHTML = roll();
}
}
document.getElementById('SpinButton').addEventListener('click', StartSpin);
As a side note, three sevens or three ones? Might want to make up your mind on that one.

They are being set to undefined because you are only setting the variables (cone, ctwo, cthree) when a 1 is randomly selected. I assume if an ace isn't drawn you want the number to be displayed?
function StartSpin() {
for (var i = 0; i < 3; i++) {
var num = Math.floor((Math.random() * 10) + 1);
if (num == 1) {
num = 'Ace';
}
document.getElementsByClassName("Spinner")[i].innerHTML = num;
}
}

You define the cone, ctwo and ctreeonly if one, two or three (respectively) equals to 1. Otherwise, variables are not initiated and that's why they are undefined.
See undefined
You can try this:
https://jsfiddle.net/0jaxL1hb/1/

Looks like you are having some trouble with how variables work. cone, ctwo, & cthree are undefined in most cases unless you get a 1. Also you only need to declare var in front of a variable when you create it. Later references just use the variable name:
var i = 1;
var j = i + 5;
console.log("i is", i, "and j is", j); // will print `i is 1 and j is 5`
A declared variable without a set value will be undefined
var k;
console.log(k); // will print `undefined`
In you code you are trying to transform 1 into the string "Ace", but you end up throwing out the values in one, two, and three in ALL other cases. This should work instead:
function StartSpin() {
// Function to make a number between 1 and 10, if 1 return "Ace" instead
function randomNumberOrAce() {
var number = Math.floor((Math.random() * 10) + 1);
// Check here if it's a `1`, and return "Ace instead", otherwise return the previously stored value
if (number === 1) {
return "Ace";
} else {
return number;
}
}
// Fill in the first three elements of ".Spinner" with three random numbers
document.getElementsByClassName("Spinner")[0].innerHTML = randomNumberOrAce();
document.getElementsByClassName("Spinner")[1].innerHTML = randomNumberOrAce();
document.getElementsByClassName("Spinner")[2].innerHTML = randomNumberOrAce();
}
<div id="GameOne">
<h1>~ Game One ~</h1>
<h2>Try to get three 7's!</h2>
<span class="so Spinner">--</span> |
<span class="st Spinner">--</span> |
<span class="sth Spinner">--</span>
<br/>
<button id="SpinButton" onclick="StartSpin()">Spin!</button>
</div>

Related

javascript: clicking numerical boxes - increment not working

using the code below, I've created a grid of buttons, 5x5, with random 1-25 numbers assigned to each button. They are to be clicked in numerical order, each's background turns red when clicked in the correct order. I can't use a global variable for this prompt. Without a global variable, I can't figure out how to increment the correctNumbers function which checks whether the right number is clicked each time. I think I'm missing something, a js function or something that would enable an incrementing variable declared within the incrementing function. I'm not looking for the whole explanation, just tips on functions i might not know about, and whether or not what i'm trying to do just isn't logicly possible.
<div id="numbers" class="hidden"></div>
<div id="youWon" class="hidden">You Won!</div>
The relevant JS:
... /**
* Gives the numbers a random order
* the "Fisher-Yates shuffle" found at: https://www.frankmitchell.org/2015/01/fisher-yates/
* #param {*} array
*/
const shuffle = (array) => {
let i = 0,
j = 0,
temp = null
for (i = array.length - 1; i > 0; i -= 1) {
j = Math.floor(Math.random() * (i + 1))
temp = array[i]
array[i] = array[j]
array[j] = temp
}
}
/**
* Generates an array of numbers 1-25
*/
const generateNums = () => {
document.getElementById("youWon").classList.toggle("hidden", "visible");
const numberArray = [];
for (let a = 1; a <= 25; a++) {
numberArray.push(a);
}
shuffle(numberArray);
let numEl = document.getElementById('numbers'); //write into html div id "numbers"
for (let b = 0; b <= 24; b++) { //loop to create button array
let newBtn = document.createElement('button'); //create buttons
newBtn.className = 'number'; //assign newBtns 'number' class
newBtn.innerText = numberArray[b]; //assign numbers to each button
numEl.appendChild(newBtn); //match with number elements in "numbers" array
newBtn.addEventListener("click", onNumberClick) //create function trigger
}
}
/**
* Creates a function to decide correct and incorrect clicks
* When a user clicks a number, if it is the next number in order, then it turns a different color for the remainder of the test
* If it is the wrong number, nothing happens
* #param {*} event
*/
const incrementNum = (correctNumber) => {
correctNumber++;
}
const onNumberClick = (event) => {
let correctNumber = 1; //start at 1
let numberVal = event.target; //apply it to clicks on the numbers
if (Number(numberVal.innerHTML) + 1 == incrementNum(correctNumber)) {
incrementNum(correctNumber);
numberVal.classList.add("red");
}
if (correctNumber == 26) {
document.getElementById("youWon").classList.toggle("visible"); //show win message if 25 is the last button and gets clicked
}
}
I would suggest that you count the number of elements in the DOM that have the class "red" and add 1... checking if the innerHTML is equal to that number to get the sequence right. So, instead of this:
if (Number(numberVal.innerHTML) + 1 == incrementNum(correctNumber)) {
incrementNum(correctNumber);
numberVal.classList.add("red");
}
You can have something like this:
if(Number(numberVal.innerHTML) == document.getElementsByClassName('red').length + 1) {
numberVal.classList.add("red");
}

How do I call this function successfully to return a value? JSON.parse()

I am trying to solve this code challenge on scale balancing. A Scale that contains two elements, the first being the two positive integer weights on a balance scale (left and right sides) and the second element being a list of available weights as positive integers.
For example, if a scale is ["[5, 9]", "[1, 2, 6, 7]"], then this means there is a balance scale with a weight of 5 on the left side and 9 on the right side. The scale can be balanced like this 2,6  
Conditions
The first element of the scale can only contain 2 weights 
It is possible to add two weights to only one side of the scale to balance it 
3.If it is not possible to balance the scale then your program should return  "Scale Imbalanced"
I have been able to do console.log of the function with hardcoded values and it worked. Also, the function returns "scale imbalanced" if none of the numbers can balance. But I can't seem to call the function dynamically.
HTML
...
<input type="text" id="balance" required>
...
<input type="text" id="weights" required>
<div class="button" id="calculateWeight" onclick="balanceIt()">
<input type="submit" value="Calculate Weight"></div>
<div id="displayResult"></div>
I want to successfully call the ScaleBalancing function to return a string if it is called. When I try ScaleBalancing([`${[balance]}`, `${[weights]}`])), it returns
Uncaught SyntaxError: Unexpected token o in JSON at position 1
at JSON.parse ()
JavaScript
function ScaleBalancing(strArr) {
let balance = JSON.parse(strArr[0]);
let weight = JSON.parse(strArr[1]);
const one = balance[0]
const two = balance[1];
for (let i = 0; i < weight.length; i++) {
let weighted = '' + weight[i];
if (one + weight[i] === two || two + weight[i] === one) {
//let weighted = '' + weight[i];
return weighted;
}
for (let j = i + 1; j < weight.length; j++) {
if (one + weight[i] + weight[j] === two ||
two + weight[i] + weight[j] === one ||
one + weight[i] === two + weight[j] ||
two + weight[i] === one + weight[j]
) {
let balancedScale = '' + weight[i] + ',' + weight[j];;
return balancedScale;
}
}
}
return 'scale imbalanced';
}
var balanceIt = function() {
let weights = document.getElementById("weights").value;
let balance = document.getElementById("balance").value;
const Scale = ScaleBalancing([`${[balance]}`, `${[weights]}`]);
document.getElementById("displayResult").innerText = Scale;
console.log(Scale);
};
document.getElementById("calculateWeight").onclick = balanceIt;
it didn't work for my either. what I did is define it from the javascript so I knew for sure that the method is defined before calling it.
I believe what happened is that the on click method is not on the same scope as the balanceIt method and that is why it's not recognised.
hope it helped you
var balanceIt = function() {
let weights = document.getElementById("weights").value;
let balance = document.getElementById("balance").value;
let scale = ScaleBalancing([`${[balance]}`, `${[weights]}`]);
document.getElementById("displayResult").innerText = scale;
};
document.getElementById("calculateWeight").onclick = balanceIt;
If your input is for example "1,2", then
`${[balance]}`
would result in just "1,2" which is not a proper JSON string.
What you want instead is probably (notice the different square bracket positions) :
ScaleBalancing([`[${balance}]`, `[${weights}]`]))

Random lottery number generator

What I'm trying to do is generate 6 random numbers, five in a range of 1-45 and one in a range of 1-25 for a Greek lottery game (Tzoker). The first 5 numbers should be unique. By pressing a button, I want to add these numbers to a div using jQuery (I have some working code for this part).
I thought it would be pretty easy using a loop, but I've found myself unable to check if the number generated already exists. The loop would only contain the first 5 numbers, because the last number can be equal to one of the other 5.
Let me propose you some simpler solution.
Make a list of all numbers from 1 to 45.
Sort the list using Math.random (plus minus something, read the docs of Array.sort to find out) as the comparison function. You will get the list in random order.
Take 5 first items from the list.
Then, when you already have the numbers, put them all into your div.
This way you don't mix your logic (getting the numbers) with your presentation (putting stuff into the DOM).
I leave the implementation as an exercise for the reader. :)
Like this?
$(function() {
$('button').on('click', function(e) {
e.preventDefault();
var numArray = [];
while( numArray.length < 5 ) {
var number = Math.floor((Math.random() * 45 ) + 1);
if( $.inArray( number, numArray ) == -1 ) {
numArray.push( number );
}
}
numArray.push( Math.floor((Math.random() * 25 ) + 1) );
$('div').html( numArray.join("<br />") );
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Generate</button>
<div></div>
While this might be not exactly what you were asking for, if you would use lodash, this would be as simple as:
_.sample(_.range(1, 46), 5) // the 5 numbers from 1..45
_.random(1, 26) // one more from 1..25
This is why functional programming is so cool. You can read for example Javascript Allonge to find out more.
http://jsfiddle.net/015d05uu/
var tzoker = $("#tzoker");
var results = $("#results");
tzoker.click(function() {
results.empty();
var properResults = [];
var rand = 0;
var contains = false;
for (i = 1; i < 7; i++) {
do
{
(rand = Math.floor((Math.random() * (i != 6 ? 45 : 25)) + 1));
contains = properResults.indexOf(rand) > -1;
} while(contains)
results.append("<br />", rand, "<br />");
properResults.push(rand);
}
});
Here is the main idea of a solution. You can define the max value as a parameter for the random.
Then, check the existence of the item in a simple array with only the data you want.
You may use a general function which generates random numbers from 1 to maxValue, and adds them to an array only if they don't exist. Then, to display, cycle through the array items and append them to #randomNumbers.
HTML
<div id="randomNumbers"></div>
JS (with jQuery)
var randomNumbersArray = [];
$(function() {
generateRandomNumbers();
displayRandomNumbers();
});
function generateRandomNumbers() {
for (i = 0; i < 5; i++) {
generateRandomNumberFrom1To(45);
}
generateRandomNumberFrom1To(25);
}
function generateRandomNumberFrom1To(maxValue) {
var randomNumber;
do {
randomNumber = Math.ceil(Math.random() * maxValue);
} while ($.inArray(randomNumber, randomNumbersArray) > -1);
randomNumbersArray.push(randomNumber);
}
function displayRandomNumbers() {
for (i in randomNumbersArray) {
$("#randomNumbers").append(randomNumbersArray[i] + "<br>");
}
}

Javascript - How do I clear out a previous value in a DIV?

i'm making a game where 2 players are fighting one another.
I have it setup where the document writes the objects hp out (100). However, when I make a event where the player suffers 10 damage, it should write out 90 in the hp bar. Instead it writes out 10090.
How can I get it where the previous value gets updated, rather than it continuing to write beside the previous value?
function player (hp, mana, stamina){
this.hp = hp;
this.mana = mana;
this.stamina = stamina;
}
function npc (hp, mana, stamina) {
this.hp = hp;
this.mana = mana;
this.stamina = stamina;
}
var alistar = new player (100, 50, 30);
var dragon = new npc (100, 50, 30);
document.getElementById("hp").innerHTML += alistar.hp;
if ( 0 < 1) {
alistar.hp = alistar.hp - 10;
document.getElementById("hp").innerHTML += alistar.hp;
}
Doing the = sign works, but it removed any HTML words I had in there. I suppose I can make a 2nd div box for my HTML needs and keep the value seperate.
Just put = symbol instead of +=:
The = operator overwrite the previous value. On the other hand, the += is the union between the + operator and the = operator, and is the "shortway" to achieve the next:
For example, if you want to add a value to a variable you can do this:
var a = 3,
value = 10; /* Your value, i.e. 10 */
a = a + value; /* a values 13 */
BUT, you can get the same result using the += operators:
var a = 3,
value = 10; /* Your value, i.e. 10 */
a = += value; /* This adds the value of a to the value of value variable. */
As you can think, the value of a is 13, too as the below example.
Regarding to your code...
CODE:
if ( 0 < 1) {
alistar.hp = alistar.hp - 10;
document.getElementById("hp").innerHTML = alistar.hp; /* UPDATE */
}
if ( 0 < 1) {
alistar.hp = alistar.hp - 10;
document.getElementById("hp").innerHTML = alistar.hp;
}
+= is concatenating the values and adding them together (seemingly in string format). Instead, you want to use "=" to assign the value of the hp to the hp element, overwriting the existing innerHTML.

javascript - generate a new random number

I have a variable that has a number between 1-3.
I need to randomly generate a new number between 1-3 but it must not be the same as the last one.
It happens in a loop hundreds of times.
What is the most efficient way of doing this?
May the powers of modular arithmetic help you!!
This function does what you want using the modulo operator:
/**
* generate(1) will produce 2 or 3 with probablity .5
* generate(2) will produce 1 or 3 with probablity .5
* ... you get the idea.
*/
function generate(nb) {
rnd = Math.round(Math.random())
return 1 + (nb + rnd) % 3
}
if you want to avoid a function call, you can inline the code.
Here is a jsFiddle that solves your problem : http://jsfiddle.net/AsMWG/
I've created an array containing 1,2,3 and first I select any number and swap it with the last element. Then I only pick elements from position 0 and 1, and swap them with last element.
var x = 1; // or 2 or 3
// this generates a new x out of [1,2,3] which is != x
x = (Math.floor(2*Math.random())+x) % 3 + 1;
You can randomly generate numbers with the random number generator built in to javascript. You need to use Math.random().
If you're push()-ing into an array, you can always check if the previously inserted one is the same number, thus you regenerate the number. Here is an example:
var randomArr = [];
var count = 100;
var max = 3;
var min = 1;
while (randomArr.length < count) {
var r = Math.floor(Math.random() * (max - min) + min);
if (randomArr.length == 0) {
// start condition
randomArr.push(r);
} else if (randomArr[randomArr.length-1] !== r) {
// if the previous value is not the same
// then push that value into the array
randomArr.push(r);
}
}
As Widor commented generating such a number is equivalent to generating a number with probability 0.5. So you can try something like this (not tested):
var x; /* your starting number: 1,2 or 3 */
var y = Math.round(Math.random()); /* generates 0 or 1 */
var i = 0;
var res = i+1;
while (i < y) {
res = i+1;
i++;
if (i+1 == x) i++;
}
The code is tested and it does for what you are after.
var RandomNumber = {
lastSelected: 0,
generate: function() {
var random = Math.floor(Math.random()*3)+1;
if(random == this.lastSelected) {
generateNumber();
}
else {
this.lastSelected = random;
return random;
}
}
}
RandomNumber.generate();

Categories

Resources