How could I correctly total the points? - javascript

I am javascript learner struggling to design a small javascript game for my kids (5 to 10 years old) in which points are based on time elapsed. But, I cannot figure out a way to total the points. I have managed the code below but the result is not accurate. Probably the program is totalling all the items in array with each click. Can anybody help please? I am a newbie and there will be many mistakes or absurdities in here, I request you to be helpful politely while correcting me. Any help is appreciated..
document.getElementById("box1").onclick = function() {
clickT = Date.now();
reactT = (clickT - createdT) / 1000; //gets the time difference for reaction.
points = reactT * 1000;
points = 2000 - points;
pRecord.push(points); //add points to array.
for (i = 0; i < pRecord.length; i++) {
totalpoints += pRecord[i];
}
document.getElementById("time").innerHTML = reactT;
this.style.display = "none";
document.getElementById("score").innerHTML = totalpoints;
}

Just set totalpoints to zero before you sum the points:
document.getElementById("box1").onclick = function() {
var clickT = Date.now();
var reactT = (clickT - createdT) / 1000; //gets the time difference for reaction.
var points = reactT * 1000;
points = 2000 - points;
pRecord.push(points); //add points to array.
var totalpoints = 0;
for (var i = 0; i < pRecord.length; i++){
totalpoints += pRecord[i];
}
document.getElementById("time").innerHTML = reactT;
this.style.display = "none";
document.getElementById("score").innerHTML = totalpoints;
}
And also I don't know if you defined your variables in the outer scope, but I guess you did not, so I added var before every variable creation.

Here is an improved version of your code that also properly registers the reaction times, capping the maximum allowed reaction time to a configured value.
In your original implementation you could get bad readings if the reaction time was greater than 2 seconds.
Also, in your original code, you don`t need to divide by 1000 and then multiply back, since you end up with milliseconds anyway.
This is it:
document.getElementById("box1").addEventListener("click", function() {
clickT = Date.now();
// Gets the time difference in milliseconds for reaction.
reactT = clickT - createdT;
// Maximum allowed reaction time after which we give no more points.
var maxPoints = 2000;
// We cap the registered reaction time to the maximum allowed.
points = Math.max(reactT, maxPoints);
// We score the reaction time based
points = maxPoints - points;
// Add points to array.
pRecord.push(points);
// Compute the total points.
var totalpoints = 0;
for (i = 0; i < pRecord.length; i++){
totalpoints += pRecord[i];
}
document.getElementById("time").innerHTML = reactT;
this.style.display = "none";
document.getElementById("score").innerHTML = totalpoints;
}
You can notice that I have defined the totalpoints variable (and initialized it with 0), as otherwise, at each click, all your scores were re-added, not just the last one.
I have made the assumption that totalpoints was not already defined before the code you have pasted. Should this assumption be wrong and you have already initialized totalpoints before, in your code, then you need to replace the following piece from my code:
// Compute the total points.
var totalpoints = 0;
for (i = 0; i < pRecord.length; i++){
totalpoints += pRecord[i];
}
...with:
// Add the new points to the total.
totalpoints += points;

Related

Increment Bitcoin Numerif Format Javascript

Hello why i try to coding something like a counter for bitcoin. this is the Code
result: <div id="counter"></div>
This is the Html
This is Javascript Code
var INTERVAL = 1; // in seconds
var INCREMENT = (0.00000001).toFixed(8); // increase per tick
var START_VALUE = (0.00000001).toFixed(8); // initial value when it's the start date
var count = 0;
$(document).ready(function() {
var msInterval = INTERVAL * 3000;
count = INCREMENT + START_VALUE;
document.getElementById('counter').innerHTML = count;
window.setInterval( function(){
count += INCREMENT;
document.getElementById('counter').innerHTML = count;
}, msInterval);
});
Heres the Output you can check
https://jsfiddle.net/8eqc2b3t/
Can anyone help
First of all, I've modified your code a little to make a bit more sense, you're using a few keywords that could be reserved within certain languages, so I'd avoid that in future ( like using count as a variable name )
var interval = 1; // in seconds
var increasePerTick = (0.00000001).toFixed(8); // increase per tick
var startingValue = (0.00000001).toFixed(8); // initial value
var $counter = $('#counter');
var btcAmount = 0.00000000;
$(document).ready(function() {
var msInterval = interval * 1000; // Convert to Milliseconds
$counter.text(startingValue); // Set initial amount
window.setInterval( function(){
btcAmount = (parseFloat(btcAmount)+parseFloat(increasePerTick)).toFixed(8);
$counter.text(btcAmount);
}, msInterval);
});
The main issue was that when you were using the + operand you were adding to the string rather than adding the two floats together. You'd also not added jQuery to your Fiddle, causing it not to work, I've fixed this and shown how to do the calculation here too, which basically is to parse both the floats, set them toFixed(8) and then print them to the counter.
The addition part is here:
btcAmount = (parseFloat(btcAmount)+parseFloat(increasePerTick)).toFixed(8);
You were also converting your msInterval incorrectly. Now seconds in interval should work out correctly when changed.
Hope this helps.
Edit:
Forgot to add the Fiddle, sorry! : https://jsfiddle.net/20Lppogq/

Thousand separator in a JavaScript counter

I have this counter JavaScript snippet:
var START_DATE = new Date("October 24, 2015 11:00:00"); // start
var INTERVAL = 1; // sec
var START_VALUE = 0; // init value
var INCREMENT = 0.13; // value per sec
var count = 0;
window.onload = function()
{
var msInterval = INTERVAL * 1000;
var now = new Date();
count = parseInt((now - START_DATE)/msInterval,10) * INCREMENT + START_VALUE;
document.getElementById('count').innerHTML = count.toFixed(2);
setInterval("count += INCREMENT; document.getElementById('count').innerHTML = count.toFixed(2);", msInterval);
}
The counter may eventually display values in thousands and millions. My question is how to separate the thousands with a comma/blank space? I tried to achieve this via CSS, but apparently the options available here are not very practical. I was wondering on a possible solution in JavaScript. I found this on jsfiddle, but I am not sure how to apply it on the result of the counter?
function addCommas(n){
var rx= /(\d+)(\d{3})/;
return String(n).replace(/^\d+/, function(w){
while(rx.test(w)){
w= w.replace(rx, '$1,$2');
}
return w;
});
}
You can use javascript's built in toLocaleString function. Here is an example from MDN
var number = 3500;
console.log(number.toLocaleString()); // Displays "3,500" if in U.S. English locale
There are some additional options you can use with that function, but they are not all supported by various browsers. Basic use should work though.

Establishing an average when counts are portioned

The problem
I have an array which is a property of the class road, which defines the allowed vehicle types on the road, and supplies an approximate portion each type contributes to traffic:
[[bus,.2],[smallCar,.6],[bigCar,.2]]
I need to calculate the average length of the cars encountered on the road, given the proportion of traffic. (This is needed to do some basic calculations elsewhere in the class.)
What I have tried:
I can't quite wrap my head around a better way to do this. In my solution, fidelity changes with an increase in car count. This seems a really slow, heavy handed approach and not right. The function to improve is named averageVehicleLaneSpace.
A very paired down but working version of much larger classes:
road = function(){};
road.prototype.averageVehicleLaneSpace = function(){
var sum = 0;
var fakeCarCount = 10000;
for( var i = 0; i< this.allowedVehicleTypes.length; i++){
var type = this.allowedVehicleTypes[i][0];
var perc = this.allowedVehicleTypes[i][1];
for(n = 0; n<=fakeCarCount*perc; n++){
sum += vehicle[type].laneSpace;
}
}
return sum/fakeCarCount;
}
//define vehicles
var vehicle = {
bus:{
laneSpace:14
},
smallCar:{
laneSpace:4
},
bigCar:{
laneSpace:4.5
}
};
var t = new road();
t.allowedVehicleTypes = [["bus",.1],["smallCar",.3],["bigCar",.6]];
alert(t.averageVehicleLaneSpace());
The Fiddle:
This Fiddle is the hopeful example above: The fiddle.
The average is the sum of the ratio * laneSpace for each vehicle type. So calculating the average is as simple as:
road.prototype.averageVehicleLaneSpace = function(){
var avg = 0;
for (var i = 0; i < this.allowedVehicleTypes.length; i++) {
var type = this.allowedVehicleTypes[i][0];
var perc = this.allowedVehicleTypes[i][1];
avg += perc * vehicle[type].laneSpace;
}
return avg;
}

Increment from zero to number in a set time

I am trying to increment from 0 to a number (can be any number from 2000 to 12345600000) within a certain duration (1000 ms, 5000 ms, etc). I have created the following:
http://jsfiddle.net/fmpeyton/c9u2sky8/
var counterElement = $(".lg-number");
var counterTotal = parseInt(counterElement.text()/*.replace(/,/g, "")*/);
var duration = 1000;
var animationInterval = duration/counterTotal;
counterElement.text("0");
var numberIncrementer = setInterval(function(){
var currentCounterNumber = parseInt(counterElement.text()/*.replace(/,/g, "")*/);
if (currentCounterNumber < counterTotal){
currentCounterNumber += Math.ceil(counterTotal/duration);
// convert number back to comma format
// currentCounterNumber = addCommas(currentCounterNumber);
counterElement.text(currentCounterNumber);
} else {
counterElement.text(counterTotal);
clearInterval(numberIncrementer);
}
console.log("run incrementer");
}, animationInterval);
function addCommas(number){
for (var i = number.length - 3; i > 0; i -= 3)
number = number.slice(0, i) + ',' + number.slice(i);
return number;
}
And this somewhat works, but it does not respect the duration. I.e. if you increase the number from 1000 to 1000000000, they both take different amounts of time to reach the destination number.
How can I increment from zero to a number in a specific time frame?
As #Mouser pointed out, the issue is that the animationInterval can't be too small (the actual minimum threshold will vary based on the browser and platform). Instead of varying the interval, vary the increment to the counter:
var counterElement = $(".lg-number");
var counterTotal = parseInt(counterElement.text()/*.replace(/,/g, "")*/);
var duration = 1000;
var animationInterval = 10;
var startTime = Date.now();
counterElement.text("0");
var numberIncrementer = setInterval(function(){
var elapsed = Date.now() - startTime;
var currentCounterNumber = Math.ceil(elapsed / duration * counterTotal);
if (currentCounterNumber < counterTotal){
counterElement.text(currentCounterNumber);
} else {
counterElement.text(counterTotal);
clearInterval(numberIncrementer);
}
console.log("run incrementer");
}, animationInterval);
I played around with your fiddle and found that the delay needs to be higher. At 8ms or 16ms, it is accurate enough to handle a second, but not accurate enough to handle half a second. From experimenting, it seems like a delay of 64ms is small enough to seem like it's incrementing smoothly, but big enough to have an accurate effect.
The difference is that the current number is calculated based on the process rather than directly manipulated.
var counterElement = $(".lg-number");
var counterTotal = parseInt(counterElement.data('total'));
var interval = 0;
var duration = parseInt(counterElement.data('duration'));;
var delay = 64
var numberIncrementer = setInterval(function(){
var currentCounterNumber = 0;
interval += delay;
if (interval <= duration){
var progress = interval / duration;
currentCounterNumber = Math.round(progress * counterTotal);
} else {
currentCounterNumber = counterTotal
clearInterval(numberIncrementer);
}
counterElement.text(currentCounterNumber);
}, delay);
http://jsfiddle.net/c9u2sky8/5/
Also: Javascript timers are not perfectly accurate. But this should be accurate enough for UI use cases.

d3 how to turn a set of numbers into a larger set representative of the first set

Say I have array [1,2,5,18,17,8] and I want to turn that into an array of length 40 that follows the same path.
a = [1,2,5,18,17,8];
stepSize = 1 / (40 / a.length);
then i think i could do something like
steps = [];
for( var i = 0; i < 1; i+= stepSize) {
steps.push(d3.interpolate(a[0],a[1])(i));
}
and then repeat that for all the elements. My question is there a better way to do this?
I can only guess what your real problem is but I think you want to plot these values and have a smooth curve. In that case use line.interpolate() https://github.com/mbostock/d3/wiki/SVG-Shapes#line_interpolate
In case you DO know what you need and your solution works for you, take this tip:
Never iterate over stepSize. Calculate it once and multiply it with i in every loop where i goes from 0 to 40. This way you work around precision problems.
Your algorithm cleaned up, tested and working:
var a = [1,5,12,76,1,2];
var steps = 24;
var ss = (a.length-1) / (steps-1);
var result = new Array(steps);
for (var i=0; i<steps; i++) {
var progress = ss * i;
var left = Math.floor(progress);
var right = Math.ceil(progress);
var factor = progress - left;
result[i] = (1 - factor) * a[left] + (factor) * a[right];
// alternative that actually works the same:
//result[i] = d3.interpolateNumber(a[left], a[right], factor);
}
console.log(result);

Categories

Resources