Making a number change gradually rather than immediately - javascript

I would like to change a number from n1 to n2 gradually that is if n1 is 5 & n2 is 10 then I want it to change like 6, 7, 8, 9, 10 instead of changing abruptly from 5 to 10
Here is the part;
var interval = setInterval(gMoneyU1, 1000);
function gMoneyU1()
{
var calc = 5 * U1Amount;
Money += calc;
document.getElementById('money').innerHTML=Money + "$";
}

I think you should use setTimeout to achieve this, I am writing a more general code but you can easily fit it to your case
var initial = 0;
var final = 5;
function change(current, expected){
if(current != expected){
setTimeout(function(){
current += ((expected-current > 0) ? 1 : -1)); //increment or decrement based on the case
change(current, expected);
}, 1000);
}
}
change(0, 5);

Here you have:
var interval = setInterval(gMoneyU1, 1000);
var Money = 0, U1Amount = 1; //Start U1Amount in 1
function gMoneyU1()
{
var calc = 5 * U1Amount;
Money += calc;
U1Amount++; //Increment amount by 1
document.getElementById('money').innerHTML=Money + "$";
}
Cheers

Here is my understanding of this question :
var money = 5,
ceiling = 10,
el = document.getElementById('money'),
tid = setInterval(update, 500);
function update() {
refresh(++money);
if (money === ceiling) clearInterval(tid);
}
function refresh(value) {
el.innerHTML = value + '$';
}
refresh(money);
Have a look at the demo : http://jsfiddle.net/wared/4DmxG/.

Related

I need to create an infinite loop

For my purpose I need to create loop where one variable is looping in this way:
0, 1, 2, 3, 4, 3, 2, 1, 0, 1, 2, 3, 4, 3, 2, 1...
It's look simple but more than hour I wonder how to do it.
My purpose is moving the star in this way
*....
.*...
..*..
...*.
....*
...*.
..*..
.*...
*....
*....
.*...
..*..
...*.
....*
Write that loop as a generator (function *... yield) and then consume it when you need it (for...of). Of course, the consuming code must provide some termination condition.
function* bounce(min, max) {
while (1) {
for (let i = min; i < max; i++)
yield i;
for (let i = max; i > min; i--)
yield i;
}
}
STEPS = 10
for(let x of bounce(0, 4)) {
console.log(x)
if (--STEPS === 0) break;
}
You can use the following code to generate the number pattern that you require. However, you wont be able to run it infinitely since it will crash the browser.
If you want to test, I have added instructions for making the loop infinite.
For you requirement, a larger value for rep variable will be enough.
let min = 0; // Start/min value
let max = 4; // Max value
let dir = 1; // Count direction (+1/-1)
let counter = min; // Your counter variable
let rep = 24; // Remove this line and change condition inside while to true for infinite loop
do {
console.log(counter);
dir = counter===max?-1:counter===min?1:dir;
counter+=dir;
} while (rep-->0); // Change this expression to true for infinite loop
You can use setTimeout or setInterval for doing that:
let number = 0;
let increment = 1;
const from = 0;
const to = 4;
const starDiv = document.getElementById("star");
function printStar(number) {
const text = [0, 1, 2, 3, 4].map(
i => (i === number) ? '*' : '-'
).join('');
starDiv.innerText = text;
}
function loop() {
printStar(number);
number += increment;
if (number == to) {
increment = -1;
} else if (number == from) {
increment = 1;
}
}
const time = 10; // 10 millisecond between step
setInterval(loop, time);
<div id="star">
</div>
You could have a simple counter and then use modulo 8 to get iterations.
let x = (i += direction) % 8;
let y = x > 4 ? 8 - x : x;
This example even prints the ascii art ;)
let i = -1;
let direction = +1;
const out = [
"*....",
".*...",
"..*..",
"...*.",
"....*",
"...*.",
"..*..",
".*...",
"*....",
];
setInterval(function() {
let x = (i += direction) % 8;
let y = x > 4 ? 8 - x : x;
window.document.write(y + " " + out[x] + "<br>");
}, 1000);
(function(min,max,max_loops)
{
for(var loop = 1; loop <= max_loops; loop++, [min,max] = [-max,-min])
{
for(num = min; num < max + (loop == max_loops); num++)
{
console.log(".".repeat(Math.abs(num)) + "*" + ".".repeat(Math.max(Math.abs(max),Math.abs(min)) - Math.abs(num)))
}
}
})(0,4,3)
But since you need an infinite loop, using generator should be more suitable.

how to calculate the ways of a big number split by some small numbers in js

For example: There is a total number 1000, and how many ways to equal 1000 using 100/50/20/10/5/1. I have found a idea about this. But obviously, that's not good. So does anyone have some other good ideas to cover it?
total = prompt('you can input number 1-1000, but 1000 will take a LOONG time');
count = 0;
t100 = total;
function money() {
for (var i100 = Math.floor(t100 / 100); i100 >= 0; i100--) {
var t50 = t100 - i100 * 100;
for (var i50 = Math.floor(t50 / 50); i50 >= 0; i50--) {
var t20 = t50 - i50 * 50;
for (var i20 = Math.floor(t20 / 20); i20 >= 0; i20--) {
var t10 = t20 - i20 * 20;
for (var i10 = Math.floor(t10 / 10); i10 >= 0; i10--) {
var t5 = t10 - i10 * 10;
for (var i5 = Math.floor(t5 / 5); i5 >= 0; i5--) {
var t1 = t5 - i5 * 5;
count++;
console.log(i100 + ' 100' + i50 + ' 50' + i20 + ' 20' + i10 + ' 10' + i5 + ' 5' + t1 + ' 1');
}
}
}
}
}
alert('The total number ' + total + ' is ' + count);
}
money()
No idea if it's correct but a little idea that popped to my head:
You know that with the bills/coins given, you can always fill up to the amount you need (value). If at the same time, you assume that you will always chose the highest possible bill / coin for the remainder I think you could do this:
If you use 100 bills you have floor(value / 100) possibilities (You can use 1 x 100, 2 x 100... )
If you don't use 100 but 50 you have floor(value / 50) possibilities
If you don't use 50 but 20 you have floor(value /20) possibilities
and so on. Add those up and you have a total of possibilities.
Let me know if I'm missing something.
I don't know about coding in js but you could try an algorithm like this one, which should be much more performant timely speaking. I'll try to make it as clear as possible :
availableCoins = [100, 50, 20, 10, 5] // all available coins exept 1
numberCoins = availableCoins.Length
mapResults = new Map[(int,int),int]
money(int total, int indexCoin){
if ( indexCoin == numberCoins ) {
return 1 // only coin 1 is available, there is only one solution
}
elseif ( mapResults.containsKey((total,indexCoin)) ) {
return mapResults((total,indexCoin)) // if the result has already been computed
}
else {
int count = 0
int currentCoin = availableCoin[indexCoin]
int upperbound = floor(total / currentCoin) // compute it before to avoid useless computation
for (int i = 0; i <= upperbound; i++) {
count += money(total - i * currentCoin, indexCoin + 1) // we assume only i of the current coin will be use
}
mapResults((total,indexCoin)) = count
return count
}
}
money(1000, 0)
Let me know if I have missed something or if it is not clear.
I let you adapt it to js.
I have got a expression from my colleague, and here it is:
//n is the total number
Change(n,m) {
if(n===0) return 0;
if(n<0 || m === 0) return 0;
var dimes = [1, 5, 10, 20, 50, 100];
return (change(n, m-1)+change(n-dimes[m-1], m));
}

How to make a JS Counter & Reset?

I am trying to make a JS counter to reach a random number and reset it self once it reaches the number and repeat again in 5 seconds.
For example: Random Number is 0.05.
0.00 > 0.01 > 0.02 > 0.03 > 0.04 > 0.05 > 0.00
<div id="current">0</div>
JS
var randomNum = Math.random();
if ( current <= randomNum ) {
for (current = 0; current < randomNum; current+=0.01) {
setInterval(function(){
current += .01;
},1000); } }
else {
current = 0;
}
You could use a closure over the variables and make a check inside of the callback, if greater then the wanted result.
This proposal uses setInterval for counting and setTimeout for the waiting time of 5 sec and the restarting with a new random value.
function startInterval() {
var randomNum = Math.floor(Math.random() * 8) + 2,
current = 0,
interval = setInterval(function() {
current += .01;
if (current > randomNum / 100) {
current = 0;
clearInterval(interval);
setTimeout(startInterval, 5000);
}
document.getElementById('current').innerHTML = current.toFixed(2);
}, 1000);
}
startInterval();
<div id="current">0</div>
Keep a counter variable outside of the loop and then simply clear it, when the desired value is reached.
var randomNum = Math.random() * 25;
var currentValue = 0;
var counter;
counter = setInterval(function() {
if (currentValue < randomNum) {
//Carefull with "0.1" as JavaScript doesn't like it!
currentValue = (currentValue * 10 + 1) / 10
}
if (currentValue > randomNum) {
currentValue = randomNum;
clearInterval(counter);
}
console.log(currentValue, '/', randomNum)
}, 1000 / 60)

Checking for two consecutive values match of a variable's value in JavaScript

I built a function called roll() which handles a roll of a dice. I'm trying to read the value of the roll and check if the roll hit 6 twice in a row so that I can interrupt the player's turn and turn it to the next player.
I can read the dice value alright, I'm having trouble trying to figure out how to check for a 6 twice in a row.
This is my function:
roll = function(){
if (gamePlaying){
// 1. Get a random number
//var dice = Math.floor(Math.random() * 6) + 1; //1 to 6 randomly
var dice = 6;
//2. Display the result
var diceDOM = document.querySelector('.dice');
diceDOM.style.display = 'block';
diceDOM.src = 'images/' + 'dice-' + dice + '.png';
//3. Update the roundScore IF the rolled number is not 1
// for type coersion, we need to use !== and not !=
if(dice !== 1) {
//add score
roundScore += dice; // same as roundScore = roundScore + dice
//it outputs to a div of ID = #myId
document.querySelector('#current-' + activePlayer).textContent = roundScore;
} else {
alert('Next Player')
nextPlayer();
}
// Is this right?
for(var i = 1; i >= 2; i++){
if (dice == 6){
console.log('sixes');
}
}
}
}
Being triggered by a button like this:
document.querySelector('.btn-roll').addEventListener('click', function(){
roll();
});
I loaded the game to this CODEPEN
P.S. I put a dice = 6; under the random function so you don't have to play the game until you get two sixes. Just uncomment it and comment out the dice = math function and you'll get nothing but sixes.
I also put a "Is this right?" comment on top of a for loop. What I mean by that is, " is this the right approach?" Should I keep experimenting with a loop or am I way off already?
And by the way, if 2 sixes do come up, the entire score is deleted which is being passed to the score[] But I can do that... I think lol
Many thanks.
You can try something like this, where you make roll() a self invoking function. That way you can store how many times they have rolled a six.
roll = (function(){
var count = 0;
var lastRoll = 0;
return function() {
if (gamePlaying){
// 1. Get a random number
var dice = Math.floor(Math.random() * 6) + 1; //1 to 6 randomly
var thisRoll = dice;
if(dice === 6) {
lastRoll = 6;
count += 1;
} else {
lastRoll = 0;
count = 0;
}
if(thisRoll === 6 && lastRoll === 6 && count === 2) {
alert('You rolled a six twice!');
lastRoll = 0;
count = 0;
// do your stuff for 2 sixes in a row here!
return;
}
//2. Display the result
var diceDOM = document.querySelector('.dice');
diceDOM.style.display = 'block';
diceDOM.src = 'http://sitedev.online/repo/' + 'dice-' + dice + '.png';
//3. Update the roundScore IF the rolled number is not 1
// for type coersion, we need to use !== and not !=
if(dice !== 1) {
//add score
roundScore += dice; // same as roundScore = roundScore + dice
//it outputs to a div of ID = #myId
document.querySelector('#current-' + activePlayer).textContent = roundScore;
console.log(dice);
} else {
alert('Next Player')
nextPlayer();
}
}
}
})();
Just for the heck of it, you don't need any global or outside vars to do this. The trick is, remember that functions are objects. You can read and write properties to them; you can even entirely change a function from within the function (which is the trick to an old JS singleton pattern).
Here's an example. If you say feed it "true", it will update the "last" reference values and return two random dice rolls. If you feed it "false", it will NOT update the previous reference values until you pass in true again (but it still returns a fresh roll). That way, you can keep rolling, hold the initial value, and compare it to a new second value all you want.
<html>
<head>
</head>
<body>
<script>
var rollfunc = function ( updateLast ) {
var d1 = Math.floor((Math.random() * 6) + 1);
var d2 = Math.floor((Math.random() * 6) + 1);
if ( updateLast ) {
rollfunc.d1 = d1;
rollfunc.d2 = d2;
}
return {
dice1 : d1,
dice2 : d2,
bothsixes : ( ( d1 + d2 === 6 ) && ( rollfunc.d1 + rollfunc.d2 === 6 ) )
};
}
var result = rollfunc ( true );
// If you pass in true then d1, d2, and rollfunc.d1, rollfunc.d2 will always be the same
console.log ( "Reference updated: ", result, "d1 = " + rollfunc.d1, ", d2 = " + rollfunc.d2 );
var result = rollfunc ( false );
// If you pass in false, the reference won't change, but the new roll will, you can compare the two
console.log ( "Reference left alone: ", result, "d1 = " + rollfunc.d1, ", d2 = " + rollfunc.d2 );
</script>
</body>
</html>
I get this might be overly academic, but it's useful to know JS can do this.
A little late to this game. But I'm new to JavaScript, and currently on a similar project from udemy.com.
Here's a solution I found that apparently works. I verified it on your CodePen, too.
document.querySelector('.btn-roll').addEventListener('click', function() {
if (gamePlaying) {
// 1. Get a random number
dice = Math.floor(Math.random() * 6) + 1; //1 to 6 randomly
thisRoll = dice;
if (dice === 6) {
lastRoll = 6;
count += 1;
} else {
lastRoll = 0;
count = 0;
}
if (thisRoll === 6 && lastRoll === 6 && count === 2) {
alert('You rolled a six twice!');
lastRoll = 0;
count = 0;
nextPlayer();
// do your stuff for 2 sixes in a row here!
return;
}
//2. Display result
var diceDOM = document.querySelector('.dice');
diceDOM.style.display = 'block';
diceDOM.src = 'http://sitedev.online/repo/' + 'dice-' + dice + '.png';
//3. Update round score if the rollled number was not a 1
if (dice !== 1) {
//Add score
roundScore += dice;
//roundScore = roundScore + dice
document.querySelector('#current-' + activePlayer).textContent = roundScore;
} else {
nextPlayer();
}
}
});
Working on the same problem. Found another solution on udemy. Hope it helps...
var lastRoll;
document.querySelector('.btn-roll').addEventListener('click', function() {
// Generating a random variable
var dice = Math.floor(Math.random() * 6) + 1;
// Check for two consecutive 6's'
if ( dice === 6 && lastDice === 6) {
//If consecutive 6's code goes here
}
lastRoll = dice;
});

Math.ceil to nearest five at position 1

Okay....
I have a lot of uncontrolled numbers i want to round:
51255 -> 55000
25 -> 25
9214 -> 9500
13135 -> 15000
25123 -> 30000
I have tried modifying the numbers as string and counting length....
But is there a simple way using some Math function maybe?
Here's my late answer. Uses no Math methods.
function toN5( x ) {
var i = 5;
while( x >= 100 ) {x/=10; i*=10;}
return ((~~(x/5))+(x%5?1:0)) * i;
}
DEMO: http://jsbin.com/ujamoj/edit#javascript,live
[51255, 24, 25, 26, 9214, 13135, 25123, 1, 9, 0].map( toN5 );
// [55000, 25, 25, 30, 9500, 15000, 30000, 5, 10, 0]
Or this is perhaps a bit cleaner:
function toN5( x ) {
var i = 1;
while( x >= 100 ) {x/=10; i*=10;}
return (x + (5-((x%5)||5))) * i;
}
DEMO: http://jsbin.com/idowan/edit#javascript,live
To break it down:
function toN5( x ) {
// v---we're going to reduce x to the tens place, and for each place
// v reduction, we'll multiply i * 10 to restore x later.
var i = 1;
// as long as x >= 100, divide x by 10, and multiply i by 10.
while( x >= 100 ) {x/=10; i*=10;}
// Now round up to the next 5 by adding to x the difference between 5 and
// the remainder of x/5 (or if the remainder was 0, we substitute 5
// for the remainder, so it is (x + (5 - 5)), which of course equals x).
// So then since we are now in either the tens or ones place, and we've
// rounded to the next 5 (or stayed the same), we multiply by i to restore
// x to its original place.
return (x + (5-((x%5)||5))) * i;
}
Or to avoid logical operators, and just use arithmetic operators, we could do:
return (x + ((5-(x%5))%5)) * i;
And to spread it out a bit:
function toN5( x ) {
var i = 1;
while( x >= 100 ) {
x/=10;
i*=10;
}
var remainder = x % 5;
var distance_to_5 = (5 - remainder) % 5;
return (x + distance_to_5) * i;
}
var numbers = [51255, 25, 9214, 13135, 25123, 3, 6];
function weird_round(a) {
var len = a.toString().length;
var div = len == 1 ? 1 : Math.pow(10, len - 2);
return Math.ceil(a / 5 / div) * div * 5;
}
alert(numbers.map(weird_round));
Also updated for numbers below 10. Won't work properly for negative numbers either, just mention if you need this.
DEMO
I'm not sure why, but I thought it would be fun with regular expressions:
var result = +(number.toString().replace(/([1-9])([0-9])(.+)/, function() {
return Math.ceil(+(arguments[1] + '.' + arguments[2])) * 10 - (+arguments[2] < 5?5:0) + arguments[3].replace(/./g, '0');
}));
Working Demo
with(Math) {
var exp = floor(log(number)/log(10)) - 1;
exp = max(exp,0);
var n = number/pow(10,exp);
var n2 = ceil(n/5) * 5;
var result = n2 * pow(10,exp);
}
http://jsfiddle.net/NvvGf/4/
Caveat: only works for the natural numbers.
function round(number) {
var numberStr = number + "",
max,
i;
if (numberStr[1] > '4') {
numberStr[0] = parseInt(numberStr[0]) + 1;
numberStr[1] = '0';
} else {
numberStr[1] = '5';
}
for (i = 2; max = numberStr.length; i < max; i += 1) {
numberStr += '0';
}
return parseInt(numberStr);
}
Strange coincidence, I wrote something really similar not so long ago!
function iSuckAtNames(n) {
var n = n.toString(), len = n.length, res;
//Check the second number. if it's less than a 5, round down,
//If it's more/equal, round up
//Either way, we'll need to use this:
var res = parseFloat(n[0]) * Math.pow(10, len - 1); //e.g. 5 * 10^4 = 50000
if (n[1] <= 5) {
//we need to add a 5 right before the end!
res += 5 * Math.pow(10, len - 2);
}
else {
//We need another number of that size
res += Math.pow(10, len - 1);
}
return res;
}

Categories

Resources