I can't seem to get this to repeat whenever past and current are the same (it's a new quote generator).
function random() { // random number 0-9
var number = Math.floor(Math.random() * 9);
return number;
}
var past = [0]; // array of past quotes
function writer() { // on button click for new random quote
var current = random();
past.push(current);
function checker() {
if (past[past.length - 2] === past[past.length - 1]) {
current = random();
checker();
}
}
checker();
}
Rekursiv geht meistens schief (sorry no English for that)
You did not change the last value if the condition is true:
var past = [-1]; // impossible value;
function writer() { // on button click for new random quote
var current = random(); // get a first random
past.push(current); // add this to past array
function checker() {
// check last two values
if (past[past.length - 2] === past[past.length - 1]) {
current = random(); // if equal, get a new random;
checker(); // re-call - BUT -
// as there' actually no change to past,
// we're in an infinite loop.
}
}
checker();
}
Change:
var past = [-1]; // impossible value;
function writer() { // on button click for new random quote
var current = random(); // get a first random
past.push(current); // add this to past array
function checker() {
// check last two values
if (past[past.length - 2] === past[past.length - 1]) {
current = random(); // if equal, set a new random even to past
past[past.length - 1] = current;
checker(); // re-call
}
}
checker();
}
Related
I'm creating a game on the web for my studies. I need to create a card game where each card has its own data (number and power name), data is taken from data.txt and put in an array that is then randomized. data.txt looks something like this:
0
Bored cat
-8
Biting
-10
Scratching
Play() function scrambles the deck when the PLAY button is pressed.
Once all cards are randomized I call a function addCardCat() which should create a card div with h1 and h3 tags. In h1 tag innerHTML should be a number, and h3 should be the power name, however, I always get returned undefined.
What could be the issue?
JS CODE
let counter = 0;
var deck = [];
// ----------READING----------//
let fs = require('fs');
let data = fs.readFileSync('data.txt', 'utf8').split('\r\n');
// ----------RANDOM NUMBER GENERATOR----------//
let numberArray = Array.from(Array(54).keys())
// ----------ARRAY SCRAMBLE---------//
function scrambleArray(array){
let currentIndex = array.length, randomIndex;
// While there remain elements to shuffle...
while (currentIndex != 0){
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
}
return array;
}
// ----------PLAYING DECK----------//
function scrambleDeck(array){
for(var i = 0; i < 54; i++){
var j = numberArray[i];
array.push(data[j*2]);
array.push(data[j*2+1]);
}
return array;
}
// ----------ADD CARD----------//
function addCardCat(number, power) {
counter++;
var newDiv = document.createElement("div");
newDiv.className += " cat__card";
newDiv.id = 'card-' +counter;
// newDiv.onclick = removeCardCat();
// newDiv.onclick = function() { alert('blah'); };
document.getElementById('cat').appendChild(newDiv);
var newH1 = document.createElement("h1");
var newH3 = document.createElement("h3");
document.getElementById('card-' +counter).appendChild(newH1);
document.getElementById('card-' +counter).appendChild(newH3);
newH1.innerHTML = number;
newH3.innerHTML = power;
return number, power;
}
// ----------START GAME----------//
function play() {
document.getElementById("play").style.display = "none";
scrambleArray(numberArray);
scrambleDeck(deck);
}```
It's hard to tell with the subminimal code provided, but it is likely that this return number, power; is causing your issue.
The return statement ends function execution and specifies a value to be returned to the function caller.
MDN
The return statement will only return a single value. You cannot use a comma-separated list. See the first snippet below for a demonstration of what happens if you use a comma-separated list.
let x = function(number, power) {
//Do stuff
return number, power;
}
console.log(x(2, 5));
Notice that you only got back the last value in the comma-separated list.
You can, however, wrap the 2 values in an array or object, for example, and then return the array or object. You can then use the appropriate destructuring method to extract the 2 values from the array or object.
Like this:
let x = function(number, power) {
//Do stuff
return [number, power];
}
console.log(x(2, 5));
That being said, it does seem odd that you are returning the same values you passed to the function as arguments without modifying them in any way.
Depending on what you do with the returned values, which unfortunately you don't show in your question, you will need to do one of the following:
Use the method I described.
Return a valid single value (including true or false) as needed.
Eliminate the return statement.
I'm making a blackjacks or 21 game, and I cannot figure out why my function value won't change, basically, this function gives you a random number, and what I want it to do is, give it a new number each time this function is called, and not the same one up to three times. (depending on the users choice.) If someone is able to solve this, I would be much appreciated, thanks.
function cardNumber(a, b) {
var cardTotal = a + b;
alert(`Your card numbers are ${a} and ${b}!`);
return cardTotal;
}
var cardRange = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var cardOne = cardRange[Math.floor(Math.random() * cardRange.length)];
var cardTwo = cardRange[Math.floor(Math.random() * cardRange.length)];
var cardSum = cardNumber(cardOne, cardTwo);
//want to give new number each time this function is called below
function moreCards(a, b) {
alert(`Your extra card is ${a}!`);
var cardTotal = a + b;
return cardTotal;
}
extraCard = cardRange[Math.floor(Math.random() * cardRange.length)];
var i;
for (i = 0; i < 3;) {
var input = prompt(`Which makes your card total ${cardSum}. Would you like to draw another card? (Type in 1 for yes, 0 for no, or select cancel to return to home.)`);
if (input === null) {
window.location.replace("http://stackoverflow.com"); //placeholder link
//take this back to home.html ^^^
i += 3;
}
//Random number doesn't change
else if (input === "1") {
i++;
cardSum = moreCards(extraCard, cardSum);
}
//Random number doesn't change
else if (input === "0") {
i += 3;
}
else {
alert("Wrong input, enter 1 or 0 on your keyboard!");
}
}
When you set a variable, it only gets set once - even if you are setting it to the return of a function. To fix your code, you need to make your variable ExtraCard into a function, such as
function extraCard() {
let newCard = cardRange[Math.floor(Math.random() * cardRange.length)]
return newCard
}
and then change where you call the variable to call it as a function, like so:
else if (input === "1") {
i++;
cardSum = moreCards(extraCard(), cardSum);
}
I'm creating a game where the computer tries to guess the user's number based on user feedback like too high or too low. I'm using a binary search. The functions work properly, however, every time the buttons are pressed, the code resets to make the original list from 1 to 100 making the guess 50 instead of remembering the new list and guess defined inside my functions.
var list = new Array();
for (i = 0; i <= 100; i++) {
list.push(i)
}
//console.log(list)
// List is intially an empty array (list). The
// for loop generates integers from
// 0 to 100 and pushes them into the array.
var guess = list[Math.floor((list.length / 2))];
console.log(guess);
var toolow = function(guess) {
while (list.includes(guess) == true) {
list.shift()
};
var guess = list[Math.floor((list.length / 2) - 1)];
console.log(list);
console.log(guess)
}
// toolow(guess)
var toohigh = function(guess) {
var last = parseInt(list.length);
while (list.includes(guess) == true) {
list.pop()
};
var guess = list[Math.round(list.length / 2)];
console.log(list);
console.log(guess)
}
// toohigh(guess)
<h1> Guess Your Number </h1>
<button id="TooLow" onclick="toolow(guess);"> Too Low</button>
<button id="TooHigh" onclick="toohigh(guess);">Too High</button>
your over use of the variable guess is causing all sorts of issues
no need to pass guess from onclick to the function
don't declare a var guess inside the functions
et voila - your code works now
var list = new Array();
for (i = 0; i <= 100; i++) {
list.push(i)
}
//console.log(list)
// List is intially an empty array (list). The
// for loop generates integers from
// 0 to 100 and pushes them into the array.
var guess = list[Math.floor((list.length / 2))];
console.log(guess);
var toolow = function() {
while (list.includes(guess) == true) {
list.shift()
};
guess = list[Math.floor((list.length / 2) - 1)];
console.log(list);
console.log(guess)
}
// toolow(guess)
var toohigh = function() {
var last = parseInt(list.length);
while (list.includes(guess) == true) {
list.pop()
};
guess = list[Math.round(list.length / 2)];
console.log(list);
console.log(guess)
}
// toohigh(guess)
<h1> Guess Your Number </h1>
<button id="TooLow" onclick="toolow();"> Too Low</button>
<button id="TooHigh" onclick="toohigh();">Too High</button>
This question already has answers here:
How to randomize (shuffle) a JavaScript array?
(69 answers)
Closed 5 years ago.
I'm trying to create a sort of a bingo number generator, where I generate a unique number and display it alone.
I also want that number + all the next numbers I'm generating to display at the bottom in a line.
My issue here is that whenever it hits a duplicate it loops until it finds a unique number, but displays that number as many times as it looped in the bottom row. So if I generate the numbers [4, 6, 2] and then another 4 it would keep looping until it found another number that's not already in the array.
If it hits the numbers in the array 2 times then found a 5, it would display as [4, 6, 2, 5, 5, 5,]. Is there anything I can do to not make it display the first 2 5's?
window.onload = startup;
function startup() {
document.getElementById("button").onclick = newNumber1;
}
var number = 0;
var bingoNumber = [];
var i;
function newNumber1() {
number = Math.floor((Math.random() * 9) + 1);
clickME();
}
function clickME() {
for (i = 0; i < bingoNumber.length; i++) {
if (number === bingoNumber[i]) {
newNumber1();
}
}
bingoNumber.splice(0, 0, number);
document.getElementById("display").innerHTML = bingoNumber[0];
document.getElementById("row").innerHTML = bingoNumber;
}
<button type="button" id="button">Click</button>
<div id="display"></div>
<div id="row"></div>
Your clickMe calls newNumber1 before it finishes executing, which isn't the problem. The problem is that newNumber1 calls another instance of clickMe, and the loop continues. So by the time newNumber1 generates a unique number, the current and previous instances of clickMe finishes inserting the same new number every time.
Another problem is that, even if you get this working, the loop in clickMe will go on and on if bingoNumber contains all possible unique number that newNumber1 can generate.
Try this:
window.onload = startup;
var bingoNumber = []; // contains all generated numbers
function startup(){
document.getElementById("button").onclick = clickMe;
}
function newNumber(){
// generate a new number
return Math.floor((Math.random() * 9) + 1);
}
function clickMe(){
// if bingoNumber contains all possible values, don't run the rest
// change this to however you want to terminate it
if(bingoNumber.length==9){ return false; }
var num; // number to add to the array
// generate a new number until it is unique
for(num=newNumber();bingoNumber.indexOf(num)>=0;num=newNumber());
// add the unique number in the beginning of the array
bingoNumber.unshift(num);
// display last generated value
document.getElementById("display").innerHTML = bingoNumber[0];
// display all generated value
document.getElementById("row").innerHTML = bingoNumber;
}
Don't add the number to array and display stuff until you really found the unique number:
var found;
function clickME() {
found = true;
for (i=0; i < bingoNumber.length; i++) {
if (number === bingoNumber[i]){
newNumber1();
found = false;
}
}
if(found) {
bingoNumber.splice(0, 0, number);
document.getElementById("display").innerHTML = bingoNumber[0];
document.getElementById("row").innerHTML = bingoNumber;
}
}
This will give you all the numbers without running out of stack space. There is an alert at the end to let you know that all the numbers have been called and will also hide the button so you can't click it again. That one you don't need...but why not?
window.onload = startup;
var bingoNumber = [];
function startup(){
document.getElementById("button").onclick = newNumber1;
}
function newNumber1() {
clickME(Math.floor((Math.random() * 9) + 1));
}
function clickME(num) {
if(bingoNumber.length < 9){
if (bingoNumber.indexOf(num) !== -1){
newNumber1();
}else{
bingoNumber.splice(0, 0, num);
document.getElementById("display").innerHTML = bingoNumber[0];
document.getElementById("row").innerHTML = bingoNumber;
}
}else{
alert("All numbers have been picked");
document.getElementById("button").style.visibility = "hidden";
}
}
I have a function where I am sending in an object, wholesaler. There is an array of objects, wholesalers which contains multiple wholesaler objects.
I need the order number of the wholesaler that just came in to be increased by 1 and then find the wholesaler object that has a current ORDER of the new value and subtract 1.
$scope.wholesalers = [];
$scope.downWholesaler = function (wholesaler) {
if (wholesaler.id > 0) {
var orderNumber = wholesaler.ORDER;
var orderBelowNumber = orderNumber + 1;
angular.forEach($scope.wholesalers, function (myWholesaler) {
if (myWholesaler.ORDER === orderNumber) {
// raise current order +1
var add = orderNumber + 1
myWholesaler.ORDER = add;
}
//setting it
if (myWholesaler.ORDER === orderBelowNumber) {
//lower one with order below number -1
var subtract = orderNumber - 1;
myWholesaler.ORDER = subtract;
}
});
console.log($scope.wholesalers);
}
};
Above I am working on doing this. I go through $scope.wholesalers and increase the current objects ORDER number and then reduce the one next to it (ORDER +1) down one.
But the ORDER is going down and the next object is not changing at all. What am I doing wrong and how do I fix it?
edit: didn't have lastest code
Fix:
$scope.downWholesaler = function (wholesaler) {
if (wholesaler.id > 0) {
var add = parseInt(wholesaler.ORDER) + 1
angular.forEach($scope.wholesalers, function (myWholesaler) {
if (myWholesaler.ORDER == add) {
myWholesaler.ORDER = parseInt(myWholesaler.ORDER) - 1;
}
});
wholesaler.ORDER = add;
console.log($scope.wholesalers);
}
};