How can I remember a past value in setInterval? - javascript

I have this function that continually generates two random numbers ranging from 0 to 7. These two numbers correspond to an id in my DOM.
How do I ensure that the next interval doesn't give the same two numbers in the same order as the last interval (in other words, the giving the same id as the LAST interval)?
If it is the case that they are the same, how do I skip this interval and go on to the next without it waiting for the interval time?
function chooserandomtile() {
cycle = setInterval(() => {
let i_random = Math.floor(Math.random() * 8);
let j_random = Math.floor(Math.random() * 8);
var id = i_random + ',' + j_random;
var target = document.getElementById(id);
if (target.classList.contains('target') || target.contains(player)) {
} else {
target.classList.add('target');
}
console.log(id);
console.log(document.getElementById(id));
}, interval);

Just declare a variable that will persist outside the scope of your method, and set it to keep track of the previous value. If your random logic produces the same ID as the previous time, try again until it gives you a different value.
function chooserandomtile() {
let lastId;
cycle = setInterval(() => {
let id;
do {
let i_random = Math.floor(Math.random() * 8);
let j_random = Math.floor(Math.random() * 8);
id = i_random + ',' + j_random;
} while (id === lastId)
lastId = id;
var target = document.getElementById(id);
if (target.classList.contains('target') || target.contains(player)) {
} else {
target.classList.add('target');
}
console.log(id);
console.log(document.getElementById(id));
}, interval);

Related

Increase a number based on Date or Interval javascript (and keep it after refresh page)

I'm struggling for while trying to figure out how to increase a number based on a Date or based on a time (Using setInterval).
I don't know which option is easier. I made it by using setInterval:
HTML
<p class="counter"></p>
JS
let tickets = 35000;
const counter = document.querySelector('.counter');
let interval = setInterval(function(){
console.log(tickets);
if (tickets >= 60000) {
var textSoldOut = `<p>¡Todo vendido!</p>`;
counter.innerHTML = textSoldOut;
console.log("Sold out");
clearInterval(interval);
}else{
var text = `¡${tickets} tickets Sold!`;
contador.innerHTML = text;
console.log(text)
}
const random = Math.floor(Math.random()*(200-100+1)+100);
tickets += random;
}, 10000);
The thing is every time the page is refreshed the counter starts from 35000 again. I am trying to figure out how to storage the var tickets. I guess this would be made by using localStorage, but since I am a beginner in JS, I am not able to do it.
Other option would be by checking the date, and based on that, show a number:
function date() {
var d = new Date();
var month = d.getMonth();
var day = d.getDate();
const counter = document.querySelector('.contador');
const random = Math.floor(Math.random()*(200-100+1)+100);
for (let i = 350000; i <= 60000 ; i++) {
if (month == 0 & day == 28) {
var sum = i + random;
document.getElementById("contador").innerHTML = suma;
}else if (mes == 0 & dia == 30) {
...
} else if (...){
...
}
}
document.getElementById("dia").innerHTML = dia;
document.getElementById("mes").innerHTML = mes;
}
fecha();
Could someone help me out to reach the result?
I would really appreciate it
The Storage object accessible via the localStorage property offers two methods to save or retrieve data: setItem and getItem().
Usage is quite simple. If you want to save the numbers of tickets into a myTickets key on localStorage you have to do it like this:
localStorage.setItem("myTickets", tickets);
To retrieve that data later on:
localStorage.getItem("myTickets");
You just have to make sure to update the myTickets key on localStorage as you increase the number of tickets inside the setinterval callback function.
let tickets = 35000;
if (localStorage.getItem("myTickets") == null) {
localStorage.setItem("myTickets", tickets);
} else {
tickets = localStorage.getItem("myTickets");
}
const counter = document.querySelector('.counter');
let interval = setInterval(function() {
console.log(tickets);
if (tickets >= 60000) {
var textSoldOut = `<p>¡Todo vendido!</p>`;
counter.innerHTML = textSoldOut;
console.log("Sold out");
clearInterval(interval);
} else {
var text = `¡${tickets} tickets Sold!`;
console.log(text)
}
const random = Math.floor(Math.random() * (200 - 100 + 1) + 100);
tickets += random;
localStorage.setItem("myTickets", tickets);
}, 10000);

JavaScript - Random numbers and variables between functions

I am new to JavaScript, I have two roll functions for each roll of a frame. I am unable to get the values of each of those rolls into a frame function to call on and use. If someone could help this would be great! thanks in advance, My code is below.
var Bowling = function() {
var STARTING_TOTAL = 0;
ROLL_ONE = Math.floor(Math.random() * 11);
ROLL_TWO = Math.floor(Math.random() * 11);
this.score = STARTING_TOTAL;
var firstScore;
var secondScore;
var totalScore;
Bowling.prototype.firstRoll = function() {
firstScore = ROLL_ONE
return firstScore;
};
Bowling.prototype.secondRoll = function() {
secondScore = Math.floor(Math.random() * 11 - firstScore);
return secondScore;
};
Bowling.prototype.frameScore = function () {
totalScore = firstScore + secondScore
return totalScore;
};
};
I can only guess what you're trying to achieve. I refactored you code a little bit:
var Bowling = function () {
var STARTING_TOTAL = 0;
this.score = STARTING_TOTAL; // remains unused; did you mean "totalScore"?
this.firstScore = 0;
this.secondScore = 0;
};
Bowling.prototype.firstRoll = function () {
this.firstScore = Math.floor(Math.random() * 11);
return this.firstScore;
};
Bowling.prototype.secondRoll = function () {
this.secondScore = Math.floor(Math.random() * 11 - this.firstScore);
return this.secondScore;
};
Bowling.prototype.frameScore = function () {
this.totalScore = this.firstScore + this.secondScore
return this.totalScore;
};
// now use it like this:
var bowling = new Bowling();
console.log(bowling.firstRoll());
console.log(bowling.secondRoll());
console.log(bowling.frameScore());
In my approach however, firstScore and secondScore are public properties.
To address the question of why the second roll can be negative: as your code currently stands, if the second roll is smaller than the first roll, the result will be negative. If you want it so that if the first roll is 6, the second roll will be a number between 0 and 4, try something like:
function randomInt(maxNum) {
return Math.floor(Math.random() * maxNum)
}
var maxRoll = 11
var rollOne = randomInt(maxRoll)
var rollTwo = randomInt(maxRoll - rollOne)
console.log(rollOne)
console.log(rollTwo)
Press "Run Code Snippet" over and over again to see it work.
Changes I've made:
I made a function, randomInt that gives a random number from 0 to some max number. This saves you from needing to write the same code twice.
I created a variable maxRoll that keeps track of what the highest possible roll is.
I subtract maxRoll from the first roll to determine what the max number for the second roll should be (maxRoll - rollOne). That's then given to randomInt.

Generate "Unique" 5 digits ID with javascript (99999 combinations) in random order

I want to generate an Unique 5 digits ID + 784 at the begining, the constraint, I can execute the script only one time, and I have to avoid the first 100 numbers so It can't be 00100 and lower. Since I use timestamp and I can execute only my script one time how I can handle this ?
I did this it's maybe dumb but at least I tried.
ConcatedID();
function ConcatedID()
{
var uniqID = checkProtectedRange();
if (checkProtectedRange())
{
var BarcodeID = 784 + uniqID;
return BarcodeID;
}
else
checkProtectedRange();
}
function checkProtectedRange()
{
var uniqueID = GenerateUniqueID();
var checkRange = uniqueID.substr(uniqueID.length - 3);
var checkRangeINT = parseInt(checkRange);
if (checkRangeINT <= 100)
return (false);
else
return (true);
}
function GenerateUniqueID()
{
var lengthID = 5;
var timestamp = + new Date();
var ts = timestamp.toString();
var parts = ts.split("").reverse();
var id = "";
var min = 0;
var max = parts.length -1;
for (var i = 0; i < lengthID; ++i)
{
var index = Math.floor(Math.random() * (max - min + 1)) + min;
id += parts[index];
}
gs.log('Generate ID ' + id);
return id;
}
Without being able to track previously used IDs, you're left with chance to prevent duplicates. Your shenanigans with Date doesn't really change that. See the birthday problem.
Given that, just follow the most straight-forward method: Generate a random string consisting of five digits.
function GenerateUniqueID() {
return ('0000'+(Math.random() * (100000 - 101) + 101)|0).slice(-5);
}
Or, if you want just the final integer with constraints applied:
function GenerateUniqueID() {
return (Math.random() * (78500000 - 78400101) + 78400101)|0;
}

Javascript: How to get the value of a function?

I am making a quick game where a player damages a enemy npc. I have a function below that does the calculation for the damage, but I can't get the console log to say i'm doing "X" amount of damage. What am I doing wrong? Instead, it just pulls up the function statement, but I want it to give me the functions value!
var damage = function() {
return Math.floor(Math.random() * 5 + 1);
};
I'm calling my function in another code properly, but when I try to console log the damage in that other code, I get a error.
function attackButton() {
darkwarrior.hp = darkwarrior.hp - damage();
console.log(darkwarrior.hp);
console.log(damage);
If you run console.log(damage()); you will get the "X" amount of damage instead of the function statement. So you could change attackButton() function to be:
function attackButton() {
var damageDealt = damage();
darkwarrior.hp = darkwarrior.hp - damageDealt;
console.log(darkwarrior.hp);
console.log(damageDealt);
I'm not sure to understand, you want to log the result? If so, you can do that:
var damage = function() {
return Math.floor(Math.random() * 5 + 1);
};
console.log(damage());
EDIT:
you forgot the (). + the value will not be the same if you don't put it in a variable:
function attackButton() {
var amount = damage()
darkwarrior.hp = darkwarrior.hp - amount;
console.log(darkwarrior.hp);
console.log(amount);
}
you just have to use an expression to assign the value to a variable. Then log it. Then return it.
var damage = function() {
var num = Math.floor(Math.random() * 5 + 1);
console.log(num);
return num;
};
damage();
Something like this should work for you.
function NPC(startingLife, name) {
this.hp = startingLife;
this.name = name
}
NPC.prototype.takeDamage = function(amount) {
this.hp = Math.max(this.hp - amount, 0);
if (this.hp == 0) {
console.log(this.name + " Dies");
}
return this.hp;
};
function damage() {
return Math.floor(Math.random() * 5 + 1);
}
var darkwarrior = new NPC(4, 'Dark Warrior');
function attackButton() {
var amount = damage();
darkwarrior.takeDamage(amount);
console.log("Dark Warrior took " + amount + " points of damage");
}
document.querySelector('#attack-button').addEventListener("click", attackButton);
<button id="attack-button">ATTACK!</button>
You are just returning the value instead of printing it. You should instead replace return with console.log(

Call random function Javascript, but not twice the same function

I use a function that randomly selects another function, which works.
But sometimes it runs the same function twice or even more often in a row.
Is there a way to prevend this?
My current code:
window.setInterval(function(){
var arr = [func1, func2, func3],
rand = Math.floor(Math.random() * arr.length),
randomFunction = arr[rand];
randomFunction();
}, 5000);
Pretty simple so far. But how do I prevent func1 (for example) to run twice in a row
You can simply store the index of the last function called and the next time, get a random number which is not the last seen index, like this
var lastIndex, arr = [func1, func2, func3];
window.setInterval(function() {
var rand;
while ((rand = Math.floor(Math.random() * arr.length)) === lastIndex) ;
arr[(lastIndex = rand)]();
}, 5000);
The while loop is the key here,
while ((rand = Math.floor(Math.random() * arr.length)) === lastIndex) ;
Note: The ; at the end is important, it is to say that the loop has no body.
It will generate a random number and assign it to rand and check if it is equal to lastIndex. If they are the same, the loop will be run again till lastIndex and rand are different.
Then assign the current rand value to the lastIndex variable, because we dont't want the same function to be called consecutively.
How about a simple check to prevent picking an index that matches the previous pick?
var arr = [func1, func2, func3, ...];
var previousIndex = false;
var pickedIndex;
if (previousIndex === false) { // never picked anything before
pickedIndex = Math.floor(Math.random() * arr.length);
}
else {
pickedIndex = Math.floor(Math.random() * (arr.length - 1));
if (pickedIndex >= previousIndex) pickedIndex += 1;
}
previousIndex = pickedIndex;
arr[pickedIndex]();
This will pick a random function in constant time that is guaranteed to be different from the previous one.
You can select random values from 0-1. And after every run, swap the recently executed function in the array with the last element in the array i.e. arr[2].
var arr = [func1, func2, func3];
window.setInterval(function(){
var t, rand = Math.floor(Math.random() * (arr.length-1)),
randomFunction = arr[rand];
t = arr[rand], arr[rand] = arr[arr.length-1], arr[arr.length-1] = t;
randomFunction();
}, 5000);

Categories